首页 > js代码的小小疑惑

js代码的小小疑惑

     function debounce(func,wait,immediate){
         var timeout;
         return function(){
             var context=this,args=arguments;
             var later=function(){
                 timeout=null;
                 //看见很多这样的写法都经常要apply一下,
                //像这种不直接 func()就可以了吗?虽然说好处是指定上下文,但这个上下文写不写都是指向window
                //为什么还要去定义?
                 if(!immediate) func.apply(context,args);
             };
             var callNow=immediate && !timeout;
             clearTimeout(timeout);
             timeout=setTimeout(later,wait);
             if(callNow) func.apply(context,args);
         };
     };

apply是指定上下文执行,但是this并不是都指向window

function fun(){
    console.log(this);
}
fun();        //指向window

var animal = function(){

}

animal.prototype = {
    species: 'all',
    say: function(){
        console.log(this);
    }
}

var dog = new animal;
dog.say()        //指向animal

至于apply的作用,无非是'借鸡生蛋',上面的例子,假如有cat = {species:'cat'},但是没有say方法,可以通过apply改变上下文来借用dog里面的say方法,稍微改下上面的例子。

var animal = function(){

        }

        animal.prototype = {
            species: 'all',

            say: function(type){
                console.log(type);
            }
        }

        var dog = new animal;
        dog.say('dog')        //dog

        var cat = {species: 'cat'};
        dog.say.apply(cat, ['cat']);        //cat

另外call作用和apply类似,但是call是参数确定时使用,apply是参数不确定时使用,当参数不确定时,内部可以通过遍历arguments数组来获取。


如果这个方法被某个dom的事件所调用,或者被new出那this就非Windows了,还有在严谨模式下。这样直接调用该方法会报错


这段代码的确context是指向window,你这代码是哪摘抄来的吧,在那里的this是指向某个对象的吧。既然你知道apply是干嘛用的,你需要用的时候用就行了,可能在他的需求里用得着这个,而你摘抄出来这一小段,用不着也不奇怪。


apply的目的在于重新指定函数执行的this对象
在这里func函数被包装了一下,返回了一个新的函数,而这个函数被作为一个普通函数调用还是会被作为一个方法调用是无法预知的,那么从兼容性及安全的角度来将,将新函数的this对象apply给func是个安全的做法,防止出现一些意向不到的情况
如下代码所示:
直接调用

var a=10;
function testFunc(){
    console.log(this.a);
}

function debounce(func){
    return function(){
        var context=this,args=arguments;
        func();
    };
}

var tempFunc=debounce(testFunc);
tempFunc();//输出 10;
var dd={
    a:20,
    func:tempFunc
};
dd.func();//输出10,而不是20

使用apply

var a=10;
function testFunc(){
    console.log(this.a);
}

function debounce(func){
    return function(){
        var context=this,args=Array.prototype.slice.call(arguments,0);
        func.apply(this, args);
    };
}

var tempFunc=debounce(testFunc);
tempFunc();//输出 10;
var dd={
    a:20,
    func:tempFunc
};
dd.func();//输出20
【热门文章】
【热门文章】