【问题标题】:Javascript changes variable between caller "methods"Javascript更改调用者“方法”之间的变量
【发布时间】:2014-12-01 08:03:36
【问题描述】:

给定:

    function testfunc(i) {

        this.foo = function() {
            i = 2;
            console.log("testfunc.foo before bar: " + i);
            this.bar();
            console.log("testfunc.foo after bar: " + i);
        };

        this.bar = function() {
            i = 3;
            console.log("testfunc.bar: " + i);
        };
    }
    
    var testvar = {
        foo: function() {
            i = 4;
            console.log("testvar.foo before bar: " + i);
            this.bar();
            console.log("testvar.foo after bar: " + i);
        },

        bar: function() {
            i = 5;
            console.log("testvarbar: " + i);
        }
    };
    
    var a = new testfunc();
    var b = Object.create(testvar);
    i = 1;
    a.foo();
    console.log("main: " + i);
    b.foo();
    console.log("main: " + i);

结果是:

"testfunc.foo before bar: 2" scope.html:37

"testfunc.bar: 3" scope.html:44

“bar 后的testfunc.foo:3” scope.html:39

"main:1" scope.html:66

"testvar.foo before bar: 4" scope.html:51

"testvarbar: 5" scope.html:58

“bar 后的testvar.foo:5” scope.html:53

"main: 5" scope.html:68

是否应该像这样,i 变量在 javascript 对象中从一个方法/函数继承到另一个方法/函数?这是否意味着在 javascript 中实例化对象的唯一安全方法是在函数上使用“new”,还是我完全忽略了这一点?

【问题讨论】:

    标签: javascript inheritance


    【解决方案1】:

    您的变量i 是一个全局变量(它没有在本地声明,所以Javascript 只是使其成为全局变量)所以无论您在哪里更改它,它都是您正在使用和修改的同一个变量。

    如果您希望 i 成为方法的本地,请将 var 放在其前面,您可以像这样声明它:

        this.foo = function() {
            var i = 2;
            console.log("testfunc.foo before bar: " + i);
            this.bar();
            console.log("testfunc.foo after bar: " + i);
        };
    

    如果您希望 i 成为您对象的属性,请使用 this.i 引用它。

        this.foo = function() {
            this.i = 2;
            console.log("testfunc.foo before bar: " + this.i);
            this.bar();
            console.log("testfunc.foo after bar: " + this.i);
        };
    

    如果您只是引用一个未定义的变量,那么 Javascript 会将其作为一个隐式全局变量,然后作为单个全局变量可供所有代码使用。

    【讨论】:

    • 哇,我把 var 关键字倒过来了,我认为这让事情变得全球化。谢谢!
    • @lash - 全局范围内的 var i; 声明会创建一个全局变量。函数范围内的 var i; 声明会创建一个局部变量。在没有任何事先声明的情况下对i 的赋值会自动创建一个全局变量(你所拥有的)。这些隐式全局变量被认为是一种不好的做法,如果您将 JS 置于严格模式下,即使现在也是一个错误(严格模式的目的是避免不良做法并让 JS 引擎帮助告诉您这些做法)。
    • 非常有帮助的答案。谢谢!
    • @lash - 因为看起来你可能是 StackOverflow 的新人,所以我想我会提到这里的程序是,如果你得到的答案实际上回答了你的问题,你可以选择通过选中该答案左侧的绿色复选标记,将其作为最佳答案,以表明您的问题已得到解答。这将为您赢得一些声誉积分,让您遵循该程序,并为提供答案的人赢得一些积分。随着时间的推移,声誉积分可以让您在网站上获得更多特权。
    • 再次感谢@jfriend00!我试图投票,但它不允许我。
    猜你喜欢
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-27
    • 2015-07-23
    • 2010-10-27
    • 1970-01-01
    相关资源
    最近更新 更多