好吧,我有一个带有一个 secret 和一种方法的构造函数:
function Keeper(get) {
var secretPower = 'wisdom';
this.get = get ? get : function () {
return 'Its secret power is: ' + secretPower;
}
// now this is privileged method only in case that there are no arguments?
}
现在我将创建两个实例,一个具有特权方法...
var yourKeeper = new Keeper();
yourKeeper.get(); // "Its secret power is: wisdom"
...但另一个不同。它可以触及周围的上下文,但不能触及构造函数的私有(private)...
var myKeeper = new Keeper(function() {
return 'Its secret power is: ' + secretPower;
});
myKeeper.get(); // ReferenceError: secretPower is not defined
...这也不能按我想要的方式工作:
myKeeper.get = function() {
return 'Its secret power is: ' + secretPower;
}
myKeeper.get(); // ReferenceError: secretPower is not defined
当然这是行不通的,因为在这些情况下 secretPower
是全局变量,所以:
var secretPower = 'none';
myKeeper.get(); // "Its secret power is: none"
那么是否可以在构造函数之外定义特权方法?如何实现?
可以用 eval 来完成吗?(我知道...这是邪恶的...我只是感兴趣)
最佳答案
是的,可以在构造函数之外定义特权方法。操作方法如下:
var Keeper = (function (key) {
function Keeper(get) {
var private = {
secretPower: "wisdom"
};
this.getPrivate = function (k) {
if (k === key) return private;
};
this.get = get || defaultGet;
}
function defaultGet() {
var private = this.getPrivate(key);
return "The secret power is: " + private.secretPower;
}
return Keeper;
}({}));
其工作原理如下:
- 我们通过创建 Immediately Invoked Function Expression (IIFE) 来创建命名空间.
- 我们创建一个名为
key
的对象。该对象对于我们刚刚创建的命名空间来说是私有(private)的。因此只有特权函数和构造函数才能访问它。 - 在构造函数内,我们创建一个名为
private
的对象,它保存每个实例的私有(private)状态。 - 我们还创建了一个名为
getPrivate
的特权方法,它接受参数k
,并且仅在k
是时才返回私有(private)对象key
我们在步骤 2 中创建。因此,只有特权函数才能访问私有(private)对象。 - 想要访问对象私有(private)状态的特权函数必须调用
getPrivate(key)
来获取私有(private)状态对象。
注意:只有当您有多个需要访问对象私有(private)状态的特权函数时,此方法才有用。此外,调用 getPrivate
会给特权函数带来(非常)小的性能开销。
顺便说一句,如果您想在 JavaScript 中编写干净的面向对象代码,请查看 augment
图书馆。使用augment
,上面的代码看起来像这样:
var Keeper = Object.augment(function (key) {
this.constructor = function (get) {
var private = {
secretPower: "wisdom"
};
this.getPrivate = function (k) {
if (k === key) return private;
};
this.get = get || defaultGet;
};
function defaultGet() {
var private = this.getPrivate(key);
return "The secret power is: " + private.secretPower;
}
}, {});
关于javascript - 是否可以在构造函数之外定义特权方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17300577/