moo*_*wer 5 javascript oop mootools private-members
我花了最近几天研究了一种在MooTools类中拥有私有或受保护属性的方法.各种文章(即Sean McArthur 在MooTools类中获取私有变量)为MooTools的弃用版本提供了一种方法,但我无法找到MooTools 1.3+的工作方法.
今天,在玩了几个小时的代码后,我想我已经创建了一个合适的解决方案.我说"思考",因为我真的不是一个经验丰富的程序员.我希望这里的社区可以查看我的代码并告诉我它是否真的是一个有效的解决方案,或者是hackjob仿真.
var TestObj = (function() {
var _privateStaticFunction = function() { }
return new Class({
/* closure */
_privates: (function() {
return function(key, val) {
if (typeof(this._data) == 'undefined') this._data = {};
/* if no key specified, return */
if (typeof(key) == 'undefined') return;
/* if no value specified, return _data[key] */
else if (typeof(val) == 'undefined') {
if (typeof(this._data[key]) != 'undefined') return this._data[key];
else return;
}
/* if second argument, set _data[key] = value */
else this._data[key] = val;
}
/* tell mootools to hide function */
})().protect(),
initialize: function() {},
get: function(val) { return this._privates(val); },
set: function(key,val) { this._privates(key,val); }
})
})();
obj1 = new TestObj();
obj2 = new TestObj();
obj1.set('theseShoes','rule');
obj2.set('theseShoes','suck');
obj1.get('theseShoes') // rule
obj2.get('theseShoes') // suck
obj1._privates('theseShoes') // Error: The method "_privates" cannot be called
obj1._privates._data // undefined
obj1._privates.$constructor._data // undefined
Run Code Online (Sandbox Code Playgroud)
我非常感谢任何提示!感谢大家!
编辑:嗯,这很尴尬.我忘了查看明显的obj1._data.我不认为这会引用实例对象!所以,我很糟糕.不过,任何想法都会很棒!
呵呵。对于你的情况,一个更简单的模式就可以解决问题。
考虑闭包后面的 var - 极难刺穿。它可以通过 getter 和 setter 获得。
缺点:数据值不能位于实例中,或者可以直接访问。
var testObj = (function() {
var data = {__proto__:null}; // 100% private
return new Class({
get: function(key) {
return data[this.uid][key] || null;
},
set: function(key, value) {
data[this.uid][key] = value;
},
remove: function(key) {
delete data[this.uid][key];
},
otherMethod: function() {
alert(this.get("foo"));
},
initialize: function() {
this.uid = String.uniqueID();
data[this.uid] = {};
}
});
})(); // why exec it?
var foo = new testObj();
var bar = new testObj();
foo.set("bar", "banana");
console.log(foo.get("bar")); // banana!
console.log(bar.get("bar")); // undefined.
bar.set("bar", "apple");
console.info(foo.get("bar"), bar.get("bar")); // banana apple
Run Code Online (Sandbox Code Playgroud)
实际应用: http: //jsfiddle.net/dimitar/dCqR7/1/
我正在努力寻找一种方法来打破这种模式——有时这可以通过像这样的原型设计来实现。
事实上,我玩过一些,这是没有命名空间的固定模式:
http://jsfiddle.net/dimitar/dCqR7/2/
var testObj = (function() {
var data = {__proto__:null}; // 100% private
return new Class({
get: function(key) {
return data[key] || null;
},
set: function(key, value) {
data[key] = value;
},
remove: function(key) {
delete data[key];
},
otherMethod: function() {
alert(this.get("foo"));
}
});
});
var foo = new new testObj();
var bar = new new testObj();
foo.set("bar", "banana");
console.log(foo.get("bar")); // banana!
console.log(bar.get("bar")); // undefined.
bar.set("bar", "apple");
console.info(foo.get("bar"), bar.get("bar")); // banana apple
Run Code Online (Sandbox Code Playgroud)
编辑一下为什么会这样...
我对 mootools 的依赖意味着我对原生 js 原型的理解还有待改进,因为它抽象了你必须直接处理这个问题,但是..
在模式一中,您定义并运行该函数,该函数创建原型并设置data- 一个单一实例。然后,您可以使用已设置的“实时”原型创建新函数data。
在模式二中,为每个实例创建和引用一个全新的原型,彼此独立。您的函数返回一个具有原型类的新函数...因此实际上new Class({});将new new <var>()创建并实例化该类。
为了更好地理解这一点,也许你可以先这样写——一个足够常见的模式,用于创建和实例化一个不被重用的类——这会更有意义:
new (new Class({
initialize: function() {
alert("hi");
}
}))();
Run Code Online (Sandbox Code Playgroud)
又可以这样写(如果保存到变量中):
var foo = new Class({
initialize: function() {
alert("hi");
}
});
new foo();
Run Code Online (Sandbox Code Playgroud)
我希望这是有道理的,我不是最擅长解释的人......