javascript - 为什么在js function里面this不能访问function里的变量(variable)
PHP中文网
PHP中文网 2017-04-10 14:27:30
[JavaScript讨论组]

大家好,

如下面的代码所示,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却不行呢?

多谢大家。

PHP中文网
PHP中文网

认证0级讲师

全部回复(5)
巴扎黑

看我对你代码的注释吧.

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
巴扎黑

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。
*/
PHPz

counter1是通过生命周期超长的那个闭包拿到count的。
js里的this到底指向的是谁,是在函数被调用时决定,同一个函数,可能会指向不同的对象。

伊谢尔伦

因为那里的this指向你返回的{inc: increase , get: getValue}对象了。楼上很多热心朋友都说了这个答案。解决办法很多,除了用that之外,也可以考虑用call、apply或者bind等方法来重置作用域。

ringa_lee

javascript中的this指向问题

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号