为什么在js function里面this不能访问function里的变量(variable)
大家好,
如下面的代码所示,counter1可以运行,counter2却不行,两者的区别是我在counter2里用了this来访问count变量。
function counter1(start){
var count = start;
var increase = function(){
count++;
};
var getValue = function(){
return count;
};
return {
inc : increase,
get :getValue }
}
var c1 = new counter1(5);
c1.inc(); //is able to increase 1
console.log(c1.get());//can return 6
function counter2(start){
var count = start;
var increase = function(){
this.count++;
};
var getValue = function(){
return this.count;
};
return {
inc : increase ,
get :getValue }
}
var c2 = new counter2(5);
c2.inc(); //can NOT access this.count
console.log(c2.get());//return NaN
我用debug工具查看counter2里面的this。发现this不包含count变量。我知道在可counter2 里面可以通过 return { count: count, inc : increase , get :getValue })这样this就能访问count了。
但是我就搞不懂,为什么counter1里面没有用this,count反而是可以访问的(即使在counter1也没有return count这个变量),而counter2却不行呢?
多谢大家。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
看我对你代码的注释吧.
原因是你这里的
increase = function() {this.count++}
中的this
指向的是这个函数返回的对象,而不是counter2
函数,关于this的指向SF已经有很多相关问题和博客了,建议你搜索一下,比如:解决方法是定义一个
that
变量给函数调用:不管你
new counter2
,还是直接调用,c2
都只是一个对象,该对象就是counter2
返回的对象,包括了inc
和get
方法。调用
inc
或get
方法时,this
得以确定(官方解释为:进入函数的执行上下文时,而不是执行函数时),就是c2
。但是c2
并没有count
属性啊。因此,可以这么做,把
count
属性也附加到返回的对象中。若想更进一步了解javascript中的
this
,请猛戳:https://github.com/goddyZhao/Translation/blob/master/JavaScript/this.mdthis
指向当前作用域的调用者。大概就是这个意思。试着分析你的c2:
楼上几位前辈已经回答得很棒了,最主要的问题就是对
this
的理解,题主不要被那层function
所疑惑,我来举个更清晰的例子:利用
Foo
作为构造函数新建一个对象:我们来看看
obj
:一清二楚了,因为这个
this
指向的是新建的对象obj
。对于
this
的理解总共有五种情形,分清楚就没问题了,题主不妨读下我译的博文:counter1是通过生命周期超长的那个闭包拿到count的。
js里的this到底指向的是谁,是在函数被调用时决定,同一个函数,可能会指向不同的对象。
因为那里的this指向你返回的
{inc: increase , get: getValue}
对象了。楼上很多热心朋友都说了这个答案。解决办法很多,除了用that之外,也可以考虑用call、apply或者bind等方法来重置作用域。javascript中的this指向问题
很经典的问题,涉及闭包、执行期上下文、作用域链。this是执行期上下文的一个属性,在进入不同上下文的时候,this值就已经确定下来,并且不会更改。参考邱俊涛的《JavaScript 核心及实践》第十章10.5.2节(this的上下文)与第七章7.3.2节(闭包应该注意的问题)。http://www.open-open.com/doc/view/ffcaed6dd21e49d690c4c08a7d40afae。