我想知道如何从JavaScript模块中的私有和公共函数访问公共属性?
例如,如果这是我的模块:
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
}
})();
sayHello
或changeName
函数都无法正常工作,因为我不知道如何访问公共name
属性。有没有办法做到这一点?我通过使用带有getter和setter的私有变量来解决它,但我想知道如果没有它们我是否可以做到。
答案 0 :(得分:5)
您需要对结果对象的引用:
var PersonModule = (function(){
function sayHello() {
alert("Hello " + person.name);
}
function privateChangeNameToBob() {
person.name = "Bob";
}
function changeName() {
privateChangeNameToBob();
}
const person = {
name: "",
sayHello,
changeName
};
return person;
})();
当然,考虑到你的单身IIFE模块,你也可以直接参考PersonModule.name
。
答案 1 :(得分:1)
在您使用它的方式中,您使用的名称变量是公共的,它与sayHello方法中的名称变量不同。您必须了解这是一个MODULE而不是需要实例化的类。 IIFE已经为您实例化了它。要做你想做的事,你可以使用下面的模型。在公共方法/变量中使用self.
,在私有中不使用任何内容。然后一切都会奏效。
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();
答案 2 :(得分:0)
您需要在闭包内声明属性。请查看此示例以更好地理解它:
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();
答案 3 :(得分:0)
this.name
中的privateChangeNameToBob
将name
设置为该功能的属性,而不是模块的属性。相反,您可以这样使用它:
var PersonModule = (function(){
var name = '';
//...
var privateChangeNameToBob = function(){
name = "Bob";
}
return {
name: name,
sayHello: sayHello,
changeName: changeName
};
})();
请参阅此处的小提琴:https://jsfiddle.net/yv8uqh5y/
最后一个注意事项是您可能觉得有用的设计模式。您可以在模块范围内声明名为base
或类似的变量,如下所示:
var PersonModule = (function(){
var base = {};
base.name = '';
base.sayHello = function() {/* ... */};
//...
return {
name: base.name,
sayHello: base.sayHello,
changeName: base.changeName
};
})();
请参阅此处的小提琴:https://jsfiddle.net/k63u9bfo/
通过这种方式,您可以引用模块的基础,而不必担心this
映射到的内容(例如,如果您尝试在内部使用{1}}内部使用this
访问模块模块方法。