“这个”上下文输出无法理解

时间:2016-12-26 07:41:47

标签: javascript

我很难理解下面的代码。

function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo
};

var a = 4;

obj.foo();
setTimeout( obj.foo, 100 );
setTimeout( obj.foo.bind(obj), 100 );

它的输出为2,4,4,我无法理解。

4 个答案:

答案 0 :(得分:2)

第一种情况,

obj.foo();

this内的foo将指向obj,因为您已将该函数指定为该特定对象的属性。

第二种情况,

setTimeout( obj.foo, 100 );

在setTimeout中,传递的函数将在窗口的上下文中eval。所以这里var a = 4;在窗口的上下文中执行,并成为窗口的属性。在函数this中访问foo时,在此特定情况下会指向window

第三种情况,

setTimeout( obj.foo.bind(obj), 100 );

您刚刚将obj this绑定到函数foo。即使在窗口的上下文中评估函数,也不会更改绑定的this值。这是bind函数背后的规则。因此,此处this不会从obj更改为window

答案 1 :(得分:2)

this关键字在差异上下文中的行为略有不同。

全球背景

在全局执行上下文中(在任何函数之外),这指的是全局对象,无论是否处于严格模式。

功能上下文

在函数内部,其值取决于函数的调用方式。

简单的通话

function foo() {
    console.log(this)
}

在非严格模式下,this将默认为全局对象

在严格模式下,this将默认为未定义

callapply

function foo() {
    console.log(this)
}
var o = {'name': 'test object'};
foo.call(o) // log object `o`
可以使用call或apply方法将

this绑定到调用中的特定对象。

bind

bind方法返回一个函数,该函数使用bind中的特定对象作为函数中的this对象。

function foo() {
    console.log(this)
}
var o = {'name': 'test object'};
bar = foo.bind(o)
bar() // log object `o`

有关详细信息,请参阅此链接:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this

解释

在这种情况下,obj.foo(); this函数fooobj,因此this.a引用obj.a

在这种情况下,setTimeout( obj.foo, 100 ); obj.too是对函数foo的引用。 setTimeout将在全局范围内执行它。

在这种情况下setTimeout( obj.foo.bind(obj), 100 );obj.foo.bind(obj)会返回对thisobj绑定的函数的引用。 setTimeout将在obj

的上下文中执行它

答案 2 :(得分:1)

您需要了解this的行为方式。它被称为函数执行上下文,您可以阅读有关here的更多信息。

在第一种情况下,函数在对象obj的上下文中调用,因为使用了属性访问器.obj.foo),因此this指向obj

在第二种情况下,将独立函数传递给setTimeout,它将在全局上下文中调用,this指向窗口。 obj.foo()var f = obj.foo; f()

不同

在第三种情况下,您将函数调用的上下文绑定到objthis再次指向obj。详细了解bind here

答案 3 :(得分:0)

尝试将alert(this);置于foo()方法中以了解上下文。

obj.foo(); =>在对象上下文中运行,因此结果将是a =>内obj的值。 2

setTimeout( obj.foo, 100 ); =>在窗口上下文中运行,var a = 4在窗口上下文中,this.a给出4 {this这里是window

并且最后一行将再次具有对象context => 2