简体   繁体   English

如何从JavaScript模块中的私有和公共函数访问公共财产?

[英]How to access public property from private and public functions in a JavaScript module?

I'm wondering how to access a public property from private and public functions in a JavaScript module? 我想知道如何从JavaScript模块中的私有和公共函数访问公共属性?

For example, if this is my module: 例如,如果这是我的模块:

var PersonModule = (function(){

    var sayHello = function(){
        alert("Hello " + name);
    }

    var privateChangeNameToBob = function(){
        this.name = "Bob";
    }

    var changeName = function(){
        privateChangeNameToBob();
    }

    return {
        name: "",
        sayHello: sayHello,
        changeName: changeName
    }   
})();

Neither sayHello or the changeName functions work correctly because I don't know how to access the public name property. sayHellochangeName函数均changeName正常工作,因为我不知道如何访问公用name属性。 Is there a way to do this? 有没有办法做到这一点? I've worked around it by using private variables with getters and setters, but I'm wondering if I can do it without them. 我已经通过将私有变量与getter和setter结合使用来解决此问题,但我想知道如果没有它们,是否可以做到这一点。

You need a reference to the result object: 您需要对结果对象的引用:

var PersonModule = (function(){
    function sayHello() {
        alert("Hello " + person.name);
    }
    function privateChangeNameToBob() {
        person.name = "Bob";
    }
    function changeName() {
        privateChangeNameToBob();
    }

    const person = {
        name: "",
        sayHello,
        changeName
    };
    return person;
})();

Of course, given your singleton IIFE module, you could just as well refer to PersonModule.name directly. 当然,考虑到您的单例IIFE模块,您也可以直接引用PersonModule.name

In the way you're doing it the name variable that you're using as public it's not the same as the one in your sayHello method. 以这种方式,您将其用作公共变量时使用的名称变量与sayHello方法中的名称变量不同。 You have to understand that this is a MODULE not a class that needs to be instantiated. 您必须了解这是MODULE,而不是需要实例化的类。 The IIFE already instantiates it for you. IIFE已经为您实例化了它。 To do what you want you can use the below model. 要执行您想要的操作,可以使用以下模型。 Use self. 使用self. in the public methods/vars and nothing in the private. 在公共方法/变量中,在私有方法中什么也没有。 Then it will all work. 这样就可以了。

 var PersonModule = (function(){ var self = {}; var privateChangeNameToBob = function(){ self.name = "Bob"; }; self.sayHello = function(){ console.log("Hello " + self.name); }; self.changeName = function(){ privateChangeNameToBob(); }; self.name = ""; return self; })(); PersonModule.name = 'Test'; PersonModule.changeName(); PersonModule.sayHello(); 

You need to declare the property inside your closure. 您需要在闭包内部声明属性。 Check this example out to understand it better: 查看此示例以更好地理解它:

var ClassName = function(constructorParam) {
 
    var privateProperty = 'Im a private property';
    this.publicProperty = 'Im a public property';
 
    function privateMethod() {
        console.log('Private method');
    }
 
    this.publicMethod = function() {
        console.log('Public method');
        // We can call private properties
        console.log(privateProperty);
        // Either private methods
        privateMethod();
    }
 
}
 
var instance = new ClassName('Here goes something to constructor');
instance.publicMethod();

Your this.name in privateChangeNameToBob is setting name as a property of that function, not of the module. 您在privateChangeNameToBob this.name privateChangeNameToBob name设置为该函数的属性,而不是模块的属性。 You can, instead, use it like so: 您可以这样使用它:

var PersonModule = (function(){
    var name = '';
    //...
    var privateChangeNameToBob = function(){
        name = "Bob";
    }
    return {
        name: name,
        sayHello: sayHello,
        changeName: changeName
    };
})();

See fiddle here: https://jsfiddle.net/yv8uqh5y/ 在这里查看小提琴: https//jsfiddle.net/yv8uqh5y/

One last note is a design pattern you may find useful. 最后一点是您可能会发现有用的设计模式。 You can declare a variable named base or similar within your module scope, like so: 您可以在模块范围内声明一个名为base或类似名称的变量,如下所示:

var PersonModule = (function(){
    var base = {};

    base.name = '';

    base.sayHello = function() {/* ... */};
    //...

    return {
        name: base.name,
        sayHello: base.sayHello,
        changeName: base.changeName
    };
})();

See fiddle here: https://jsfiddle.net/k63u9bfo/ 在这里查看小提琴: https//jsfiddle.net/k63u9bfo/

This way you can reference the base of your module without having to worry what this maps to (eg. if you're trying to access the module internally using this within an anonymous function declared within a module method. 这样,您可以引用模块的基础,而不必担心this映射到什么(例如,如果您试图在模块方法中声明的匿名函数中使用this内部访问模块。

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

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