如何从 JavaScript 模块模式中的私有(private)函数调用公共(public)函数?
例如,在下面的代码中,
var myModule = (function() {
var private1 = function(){
// How to call public1() here?
// this.public1() won't work
}
return {
public1: function(){ /* do something */}
}
})();
这个问题有人问过twice before ,每个都有不同的可接受答案。
- 在返回之前保存对返回对象的引用,然后使用该引用访问公共(public)方法。参见 answer .
- 在闭包中保存对公共(public)方法的引用,并使用它来访问公共(public)方法。参见 answer .
虽然这些解决方案有效,但从 OOP 的 Angular 来看它们并不令人满意。为了说明我的意思,让我们用这些解决方案中的每一个来具体实现一个雪人,并将它们与一个简单的对象字面量进行比较。
雪人 1:保存对返回对象的引用
var snowman1 = (function(){
var _sayHello = function(){
console.log("Hello, my name is " + public.name());
};
var public = {
name: function(){ return "Olaf"},
greet: function(){
_sayHello();
}
};
return public;
})()
雪人 2:保存对公共(public)函数的引用
var snowman2 = (function(){
var _sayHello = function(){
console.log("Hello, my name is " + name());
};
var name = function(){ return "Olaf"};
var public = {
name: name,
greet: function(){
_sayHello();
}
};
return public;
})()
雪人 3:对象字面量
var snowman3 = {
name: function(){ return "Olaf"},
greet: function(){
console.log("Hello, my name is " + this.name());
}
}
我们可以看到这三者在功能上是完全相同的,并且具有完全相同的公共(public)方法。
但是,如果我们运行一个简单覆盖的测试
var snowman = // snowman1, snowman2, or snowman3
snowman.name = function(){ return "Frosty";}
snowman.greet(); // Expecting "Hello, my name is Frosty"
// but snowman2 says "Hello, my name is Olaf"
我们看到 #2 失败了。
如果我们运行原型(prototype)覆盖测试,
var snowman = {};
snowman.__proto__ = // snowman1, snowman2, or snowman3
snowman.name = function(){ return "Frosty";}
snowman.greet(); // Expecting "Hello, my name is Frosty"
// but #1 and #2 both reply "Hello, my name is Olaf"
我们看到 #1 和 #2 都失败了。
这是一个非常糟糕的情况。仅仅因为我选择以一种或另一种方式重构我的代码,返回对象的用户必须仔细查看我是如何实现所有内容的,以确定他/她是否可以覆盖我的对象的方法并期望它工作!虽然这里的观点不同,但我个人认为正确的覆盖行为是简单对象文字的覆盖行为。
所以,这才是真正的问题:
有没有一种方法可以从私有(private)方法调用公共(public)方法,以便生成的对象在覆盖行为方面像对象文字一样?
最佳答案
您可以使用 this
获取您的特权方法 greet
被调用的对象。
然后,您可以将该值传递给您的私有(private)方法 _sayHello
,例如使用 call
、apply
或作为参数:
var snowman4 = (function() {
var _sayHello = function() {
console.log("Hello, my name is " + this.name);
};
return {
name: "Olaf",
greet: function() {
_sayHello.call(this);
}
};
})();
现在你可以做
var snowman = Object.create(snowman4);
snowman.greet(); // "Hello, my name is Olaf"
snowman.name = "Frosty";
snowman.greet(); // "Hello, my name is Frosty"
还有
snowman4.greet(); // "Hello, my name is Olaf"
snowman4.name = "Frosty";
snowman4.greet(); // "Hello, my name is Frosty"
关于javascript - 如何从 JavaScript 模块模式中的私有(private)函数中调用公共(public)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32059222/