在这段代码中,为什么foo和this.foo引用不同的东西?

Jay*_*Jay 6 javascript closures

这是代码:

for (var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i); //prints 9 10 times
        console.log(this.i); //prints 0, 1, 2...9
    }.bind({i:i}), i * 1000);
}
Run Code Online (Sandbox Code Playgroud)

为什么i以及this.i是指不同的东西?

将此与在全局范围内执行的一些代码进行对比:

var x = 5;
console.log(x);
console.log(this.x);//both will print 5
Run Code Online (Sandbox Code Playgroud)

这里的范围是全球性的,背景也是如此.变量声明在全局上下文中设置相同名称的属性.另一方面,在函数范围内,这不会发生.

var a = function() {
    var x = 5;
    console.log(x); //5
    console.log(this.x); //undefined
    console.log(i);  //undefined
    console.log(this.i);  //10

}.bind({i: 10});
a();
Run Code Online (Sandbox Code Playgroud)

即使我们将全局上下文传递到本地范围,在函数中声明变量也不会将其设置为全局上下文的属性.

var a = function() {
    var x = 5;
    console.log(x); //5
    console.log(this.x); //undefined
}.bind(window);
a();
console.log(x); //undefined
console.log(this.x); //undefined
Run Code Online (Sandbox Code Playgroud)

我想说的是:在全局范围内,变量声明修改全局上下文.但是在函数作用域中,无论上下文是什么,变量声明都不会修改函数的上下文.为什么?

Cym*_*men 2

当您想到窗口上的全局作用域时,它会很有帮助。所以你可以说全局在窗口上下文中运行。所以真的:

var x = 5;
console.log(x);
console.log(this.x);//both will print 5
Run Code Online (Sandbox Code Playgroud)

最后一行thiswindowso you are running console.log(window.x)

当您使用 时,您会更改“绑定”函数内部bind的引用。this例如:

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

log(); // logs 10

log.bind({x: 20})()  // logs 20
Run Code Online (Sandbox Code Playgroud)

该调用在 be 中bind进行了对我们使用 创建的匿名对象的引用。你也可以这样做:thislog{x: 20}

var myObject = {x: 50};
log.bind(myObject)(); // logs 50
Run Code Online (Sandbox Code Playgroud)