这是代码:
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);
}
为什么i
和this.i
指的是不同的东西?
将此与在全局范围内执行的一些代码进行对比:
var x = 5;
console.log(x);
console.log(this.x);//both will print 5
这里的范围是全球性的,背景也是全球性的。变量声明在全局上下文上设置同名的属性。另一方面,在函数范围内,这不会发生。
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();
即使我们将全局上下文传递到局部范围,在函数中声明变量也不会将其设置为全局上下文的属性。
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
我想说的是:在全局范围内,变量声明修改了全局上下文。但在函数作用域中,变量声明不会修改函数的上下文,无论上下文是什么。为什么?
当您想到全局范围在窗口上时,它会有很大帮助。因此,您可以说全局运行在窗口的上下文中。所以真的:
var x = 5;
console.log(x);
console.log(this.x);//both will print 5
在最后一行中,this
window
,因此您正在运行console.log(window.x)
。
当你使用 bind
时,你会在 "bound" 函数中更改this
的引用。例如:
var x = 10;
function log() {
console.log(this.x);
}
log(); // logs 10
log.bind({x: 20})() // logs 20
bind
调用已使this
成为log
引用我们使用{x: 20}
创建的匿名对象。您也可以这样做:
var myObject = {x: 50};
log.bind(myObject)(); // logs 50
再考虑一下,这种行为是有道理的。感谢所有评论和回答的人。它帮助我更多地思考了这件事。
- 从基础开始,在 JavaScript 中,变量的作用域仅限于定义它的函数。
- 在全局范围内,var 声明会将 var 设置为全局上下文的属性(fine)
-
如果我们希望在函数作用域中具有相同的行为,var 声明将修改函数的上下文对象。但这有以下问题:
一个。如果函数的上下文是某个对象,则函数中的每个 var 声明都将设置为对象的属性。所以这会发生:
函数具有对象上下文:
//if var declarations inside functions modified context
//this doesn't happen in reality
var ctx = {b: 5};
var a = function() {
var c = 7;
this.b = 10;
}.bind(ctx);
a();
console.log(ctx.b); //10, as expected
console.log(ctx.c); //7, wtf? I never set this
二.如果未设置函数的上下文,则其上下文是全局对象。我们已经知道这一点。但是,如果允许函数中的 var 声明以与全局范围内的 var 声明相同的方式修改上下文,那么功能范围将变得毫无意义
函数具有全局上下文:
function a() {
var b = 5;
this.c = 10; //this refers to window. it is this function's context
}
a();
console.log(b); //outputs 5 if function vars could modify context, which means functional scope is dead
console.log(c); //outputs 10, as expected
这就是为什么var
函数内外的工作方式不同。