简体   繁体   English

javascript私有函数访问公共变量

[英]javascript private function access public variable

i have this class: 我有这堂课:

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }
}

and call it : 并称之为:

    var myobj = new ctest();
    myobj.func1();

isn't supposed that the second alert will popup "huhu" ? 是不是第二个警报会弹出“huhu”? func2 is private, can it not access the var1 public variable ? func2是私有的,是否可以访问var1公共变量?

if a private function cannot access a public variable, how can i do it ? 如果私有函数无法访问公共变量,我该怎么办?

Thanks in advance! 提前致谢!

You need to provide a context for the call to func2 : 您需要为func2调用提供上下文:

this.func1 = function() {
    alert(this.var1);
    func2.call(this);
    alert(this.var1);
}

Without the context the call will use the global object (ie window ) - you should see when you run your current code that window.var1 is getting created between the two alerts. 如果没有上下文,调用将使用全局对象(即window ) - 您应该看到在运行当前代码时,在两个警报之间创建了window.var1

Functions are not tied to instances, therefore your invocation of func2 ends up as invocation without this pointing to the expected instance. 功能不依赖于实例,因此您的调用func2最终成为调用,而不this指向预期的实例。

You can either fix the invocation to include the context: 您可以修复调用以包含上下文:

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2.call(this);
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }
}

Or you can keep a variable with the wanted object reference around: 或者您可以使用所需对象引用保留变量:

function ctest() {
    var that = this;
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        that.var1 = "huhu";
    }
}

Another option is to use Function.bind : 另一种选择是使用Function.bind

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }.bind(this);
}

Note that the browser support for this is not perfect. 请注意,浏览器对此的支持并不完美。

There is no such thing as private in JS, but you can play with scopes using the closures . 在JS中没有private这样的东西,但你可以使用闭包来使用范围。

Let's say for instance that in your example you don't need to expose var1 as public property. 比方说,例如,在您的示例中,您不需要将var1公开为公共属性。 You could easily rewrite your code as the follows: 您可以轻松地重写代码,如下所示:

function ctest() {
    var var1 = "haha";

    this.func1 = function() {
        alert(var1);
        func2();
        alert(var1);
    }

    var func2 = function() {
        var1 = "huhu";
    }
}

Because both func1 and func2 shares the same scope – they are defined in the same function, ctest – they can access to the same variables. 因为func1func2共享相同的范围 - 它们在同一个函数ctest中定义 - 它们可以访问相同的变量。 Of course in that case you don't have var1 exposed, so: myobj.var1 will be undefined . 当然,在这种情况下,您没有暴露var1 ,因此: myobj.var1将是undefined

If you want var1 to be exposed as property, then what you need is bind func2 to the object instance you created in the constructor: 如果您希望将var1公开为属性,那么您需要 func2 绑定到您在构造函数中创建的对象实例:

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var func2 = function() {
        this.var1 = "huhu";
    }.bind(this);
}

Otherwise func2 will have a different context object ( this ). 否则func2将具有不同的上下文对象( this )。 If the browser doesn't support bind and you don't want use a shim (as shown in the link above), you can take advantage of the closures again: 如果浏览器不支持bind并且您不想使用填充程序(如上面的链接所示),则可以再次利用这些闭包:

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2();
        alert(this.var1);
    }
    var context = this;
    var func2 = function() {
        context.var1 = "huhu";
    }
}

IMVHO is less elegant. IMVHO不那么优雅。

function ctest() {
    this.var1 = "haha";
    this.func1 = function() {
        alert(this.var1);
        func2(this);
        alert(this.var1);
    }
    var func2 = function(obj) {
        obj.var1 = "huhu";
    }
}

And there is other way to solve this problem, check the other answers :) 并有其他方法来解决这个问题,检查其他答案:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM