理解变量创建

时间:2014-07-31 05:25:13

标签: javascript

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()?

2 个答案:

答案 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.incfunc中存储的匿名函数时,默认上下文变为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