![](/img/trans.png)
[英]Javascript classes define attribute in constructor or outside the class
[英]Is it possible to define priviledge method outside of the constructor?
好吧,我有一个带有一个秘密和一个方法的构造函数:
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"
...但是另一个是不同的。 它可以触及周围的上下文,但不能触及构造函数的私有对象。
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完成吗? (我知道...这很邪恶...我只是有兴趣)
在javascript中进行范围界定的基本想法是,这不应该实现,我建议在构造函数的范围内添加一个函数getPrivate
,并使用该函数来访问“私有”变量。
function Keeper(get) {
var semiPrivates = {
secretPower:'Wisdom'
}
this.getPrivate = function (variable){
return semiPrivates[variable];
}
this.get = get ? get : function () {
return 'Its secret power is: ' + semiPrivates["secretPower"];
}
}
是的,可以在构造函数之外定义特权方法。 这是操作方法:
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;
}({}));
下面是它的工作原理:
key
的对象。 该对象是我们刚创建的名称空间的私有对象。 因此,只有特权函数和构造函数才能访问它。 private
的对象,该对象保存每个实例的私有状态。 getPrivate
的特权方法,该方法带有参数k
并且如果k
是我们在步骤2中创建的key
,则仅返回私有对象。因此,只有特权函数才能访问私有对象。 getPrivate(key)
以获得私有状态对象。 注意:仅当您具有多个需要访问对象的私有状态的特权函数时,此方法才有用。 另外, 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;
}
}, {});
我永远不会这样做,但这是eval
的解决方案:
function test(){
var private = 'hello';
this.say = function(){
}
this.setSay = function(func){
eval('this.say = ' + func.toString());
}
}
var x = new test();
x.setSay(function(){
console.log(private + ' world');
});
x.say();
示例http://jsfiddle.net/claustrofob/AwMd3/
以下是与Keeper
对象相关的示例:
function Keeper(get) {
var secretPower = 'wisdom';
var getFunc = function () {
return 'Its secret power is: ' + secretPower;
};
var evalFunc = function(variable, val){
eval(variable + ' = ' + val.toString());
};
this.__defineSetter__("get", function(val){
evalFunc('getFunc', val);
});
this.__defineGetter__("get", function(val){
return getFunc;
});
if (get !== undefined){
evalFunc('getFunc', get);
}
}
在这里,我们为您的get
方法定义了setter和getter,以便您可以通过以下方式初始化对象:
var x = new Keeper(function () {
return 'Its secret power is: ' + secretPower;
});
这样:
var x = new Keeper();
x.get = function () {
return 'Its secret power is: ' + secretPower;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.