【Web前端问题】为什么在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却不行呢?

多谢大家。

请输入图片描述

回答:

看我对你代码的注释吧.

function counter1(start){ 

var count = start;

var increase = function(){

// 这里访问的count就是 上面声明的那个, 这里的概念是 闭包

count++;

};

var getValue = function(){

// 这里访问的count就是 上面声明的那个, 这里的概念是 闭包

return count;

};

return {

inc : increase,

get :getValue }

}

var c1 = new counter1(5);

// 下面两行调用的函数属于闭包返回的, 本质访问的是counter1里声明的那个count

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. 这里你需要理解this到底指向谁(与C++里的this不同)

this.count++;

};

var getValue = function(){

// 这里访问的是this的count. 这里你需要理解this到底指向谁(与C++里的this不同)

return this.count;

};

return {

inc : increase ,

get :getValue }

}

var c2 = new counter2(5);

// 这里访问inc时, this指针指向c2, 由于c2中没有count属性;

// 所以其实调用this.count++之前this.count的值是undefined;

// 对一个undefined的值做++操作返回NaN, 即this.count++之后this.count的值是NaN;

// 此时调用c2.get()返回NaN.

c2.inc(); //can NOT access this.count

console.log(c2.get());//return NaN

回答:

原因是你这里的increase = function() {this.count++}中的this指向的是这个函数返回的对象,而不是counter2函数,关于this的指向SF已经有很多相关问题和博客了,建议你搜索一下,比如:

解决方法是定义一个that变量给函数调用:

var counter2 = function() {

this.count = 0;

var that = this;

var increase = function() {return that.count++};

return {count:this.count, increase: increase};

}

回答:

不管你new counter2,还是直接调用,c2都只是一个对象,该对象就是counter2返回的对象,包括了incget方法。

调用incget方法时,this得以确定(官方解释为:进入函数的执行上下文时,而不是执行函数时),就是c2。但是c2并没有count属性啊。

因此,可以这么做,把count属性也附加到返回的对象中。

function counter2(start){ 

var count = start;

var increase = function(){

this.count++;

};

var getValue = function(){

return this.count;

};

return {

count:count,

inc : increase ,

get :getValue }

}

若想更进一步了解javascript中的this,请猛戳:https://github.com/goddyZhao/Translation/blob/master/JavaScript/this.md

回答:

this指向当前作用域的调用者。大概就是这个意思。

试着分析你的c2:

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:

传入参数start=5;

定义并赋值内部变量count=5

定义increase和getValue函数表达式

将一个匿名对象赋值给c2,对象包含inc和get两个属性,分别指向两个函数。

*/

c2.inc(); //can NOT access this.count

/*

直接执行对象c2下的inc函数。由于是直接执行函数,函数中的this将被指向函数的调用者:对象c2。

increase函数试图查找this.count,即c2.count,并执行++操作。

由于对象c2中不存在count属性,对一个undefined对象进行++操作时生成NaN,即c2.count被赋值为NaN。

*/

console.log(c2.get());//return NaN

/*

直接执行对象c2下的get函数。函数this指向c2,因此返回在c2.count。由于在increase中,c2.count被赋值为NaN,因此返回NaN。

*/

回答:

楼上几位前辈已经回答得很棒了,最主要的问题就是对 this 的理解,题主不要被那层 function 所疑惑,我来举个更清晰的例子:

function Foo() {

var a = 1;

return {

A: this.a

}

}

利用 Foo 作为构造函数新建一个对象:

var obj = new Foo();

我们来看看 obj

请输入图片描述

一清二楚了,因为这个 this 指向的是新建的对象 obj

对于 this 的理解总共有五种情形,分清楚就没问题了,题主不妨读下我译的博文:

《细说 Javascript 函数篇(二) : 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

以上是 【Web前端问题】为什么在js function里面this不能访问function里的变量(variable) 的全部内容, 来源链接: utcz.com/a/140007.html

回到顶部