什么是"这"在setTimeout的回调中?

时间:2017-09-09 20:52:01

标签: javascript this

为新手问题道歉,但请考虑此代码

function Greeter( name) { this.name = name; }

Greeter.prototype.delayed_greet = function() { 
  setTimeout( function cb() { 
    console.log(' Hello ' + this.name); 
  }, 500); 
};

Greeter.prototype.greet = function() { 
    console.log(' Hello ' + this.name); 
}

const greeter = new Greeter(' World');

greeter.delayed_greet(); // will print "Hello undefined"
greeter.greet(); // will print "Hello World"

所以在delayed_greet方法中,thissetTimeout内嵌套时会引用什么?它显然不是指greeter对象,否则它会起作用。

1 个答案:

答案 0 :(得分:3)

setTimeout通常在浏览器中定义为window.setTimeout,并且可以仅作为setTimeout调用,因为它在全局范围内可用。

这也意味着上下文和this值始终为window,除非明确设置了另一个this值。

MDN

  

setTimeout()执行的代码从执行上下文调用   与调用setTimeout的函数分开。

     

为被调用函数设置this关键字的常用规则   如果您未在呼叫中设置this或使用绑定,则应用它   将以非严格模式默认为全局(或窗口)对象,或   在严格模式下未定义。

     

它与函数的this值不同   叫做setTimeout。

MDN还概述了解决这个问题的多种方法"在setTimeout。 我个人认为我会采取简单的方法,并使用变量

Greeter.prototype.delayed_greet = function() { 
   var that = this;

   setTimeout( function cb() { 
       console.log(' Hello ' + that.name); 
   }, 500); 
};

另一种选择是箭头功能,因为它们保留了周围环境,并且不会创建自己的上下文。



var o = { 
    fn () { 
        setTimeout( () => { console.log(this) }, 500) 
    } 
}

var o2 = { 
    fn () { 
        setTimeout( function() { 
            console.log(this === window) 
        }, 1000) 
    } 
}

o.fn();  // fn()              ---  arrow function
o2.fn(); // true, is window   ---  regular function




相关问题