var counter = {
count: 0,
inc: function(){
this.count++;
}
}
counter.inc();
count;
//reference error: count is not defined
但是当我使用变量并调用函数时:
var counter = {
count: 0,
inc: function(){
this.count++;
}
}
var func = counter.inc;
func();
count;
// returns NaN Because func() runs window.count++
我的问题是,如果不使用变量并调用函数,为什么不创建计数变量?
+----------------------------------------------------------------+
| counter.inc() not equal to window.count++ |
| but func() equal to window.count++ |
| |
+-------Why?-----------------------------------------------------+
我的关键问题是:
为什么它的不同是counter.inc()和var func = counter.inc; func()?
答案 0 :(得分:1)
初步:
表达式时:
this.count++;
被评估, this 引用全局(浏览器中的窗口)对象,因此它是有效的:
window.count++;
this 引用全局对象的原因在其他问题的答案中有解释。
我的问题是,如果不使用变量并调用函数,为什么不创建计数变量?
它正在创建 count 作为全局对象的属性,这与使用变量语句(即var count
)非常相似,但在其他地方有细微差别。
评估表达式时:
window.count++
首先解析 window.count 。由于 window 没有 count 属性,因此返回 undefined 。然后,++
运算符会对 ToNumber(未定义)进行评估,并返回 NaN 。然后,它会根据+运算符的规则尝试将1添加到 NaN ,这将返回 NaN 。
然后它将调用 PutValue(window.count, NaN) 并且由于 window.count 不存在,它将创建它并分配值 NaN
当您将该功能称为:
时counter.inc();
然后这个在函数中是计数器对象,所以:
this.count++;
增加其 count 属性的值。
当你这样做时:
var func = counter.inc;
func();
然后函数中的 this 不是由调用设置的,因此它默认为全局对象。上面的内容告诉您为什么导致 window.count 设置为 NaN ,这会导致任何属性或变量的值解析为 NaN 当 ToNumber 应用于它时。
如果要创建全局 count 变量并在调用 func 之前将其初始化为数字值(例如0
):
var count = 0;
func();
然后调用 func 会导致其值递增。
答案 1 :(得分:1)
当您存储counter.inc
中func
中存储的匿名函数时,默认上下文变为window
。然后,当您调用func
时,由于您没有传入上下文,因此它的上下文默认为window
,它没有count属性。由于window.count++
未定义,因此window.count
会将NaN
设置为window.count
。
window.prop = 2;
var A = {
prop: 1,
go: function () {
console.log(this.prop);
}
}
A.go(); // 1
var B = {
prop: 3,
go: A.go
}
B.go(); // 3
window.go = A.go;
window.go(); // 2