对象的方法中 setTimeout作用

        var a=0;
         var obj = {
             a:'obj',
             b:function(a){
                 console.log(this.a);
             }
         }
         obj.b(1);//obj                   (1)
        obj.b.call(this,1);//0           (2)
        obj.b.apply([1]);//undefined     (3)

====================================================

         var a=0;
         var obj = {
             a:'obj',
             b:function(a){
                 setTimeout(function(){
                     console.log(this.a);
                 },1000)
             }
         }
         obj.b(1);//0                    (4)
        obj.b.call(this,1);//0           (5)
        obj.b.call(1);//0                (7)
        obj.b.apply([1]);//0             (8)
        obj.b.apply(null,[1]);//0        (9)
        obj.b.apply(this,[1]);//0        (10)

问题一:比较(1)和(4),setTimeout所起的作用是什么呢?
问题二:比较(3)和(8),为何(8)中就有值,而(3)没有?
问题三:为何传入值没有任何作用?

阅读 3.1k
3 个回答

超时调用的代码都是在全局作用域中执行的,因此函数中this的值在非严格模式下指向window对象,在严格模式下是undefined.
问题一二三都是一个解释:setTimeout是全局作用域中执行的,所以this.a指向全局变量 var a = 0;

setTimeout 函数回调的context(this)默认是window
改成这样:

var a=0;
var obj = {
     a:'obj',
     b:function(a){
         // 这里的this, 是call和apply的第一个参数, 要使用这个context, 可以这么写
         var context = this; // 每个function内的this不一定相同, 缓存以供下游代码使用
         setTimeout(function(){
             // 这里的this默认等于window, log(this.a) 将会是0
             console.log(context.a);
         },1000)
     }
 }

this的隐式绑定在发生参数传递时会造出绑定丢失,从而应用默认绑定而绑定到全局对象;apply的第一个参数为null或undefined时会自动指向全局对象。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题