【问题标题】:Private Properties in MooTools 1.3+ ClassesMooTools 1.3+ 类中的私有属性
【发布时间】:2011-05-23 23:09:48
【问题描述】:

过去几天我一直在研究一种在 MooTools 类中具有私有或受保护属性的方法。各种文章(即 Sean McArthur 的 Getting Private Variables in a MooTools Class)提供了一种处理已弃用的 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

我非常感谢任何提示!谢谢大家!

编辑:嗯,这很尴尬。我忘了检查显而易见的 obj1._data。我不认为 this 会引用实例对象!所以,我很烂。不过,任何想法都会很棒!

【问题讨论】:

  • 您不希望您的 getter 和 setter 调用与字典交互的私有函数吗?即get: function(val) { return getFunc(val); }

标签: javascript oop mootools private-members


【解决方案1】:

嘿嘿。在你的情况下,一个更简单的模式就可以了。

考虑闭包后面的 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

实际操作中:http://jsfiddle.net/dimitar/dCqR7/1/

我正在努力寻找一种方法来彻底打破这种模式——这有时可以通过像this 这样的原型设计来实现。

事实上,我玩过它,这是没有命名空间的固定模式:

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

编辑为什么...

我对 mootools 的依赖意味着我对原生 js 原型的理解还有待改进,因为它抽象出你必须直接处理这个问题,但是..

在模式一中,您定义并运行该函数,该函数创建原型并设置data - 一个单一实例。然后,您可以使用已设置 data 的“实时”原型创建新函数。

在模式二中,为每个实例创建和引用一个全新的原型,彼此独立。你的函数返回一个带有原型类的新函数......所以new Class({}); 因此new new <var>() 将创建并实例化该类。

为了更好地理解这一点,也许您可​​以先这样编写它 - 一种用于创建和实例化未被重用的类的足够常见的模式 - 这将更有意义:

new (new Class({
    initialize: function() {
        alert("hi");
    }
}))();

又可以这样写(如果保存到变量中):

var foo = new Class({
    initialize: function() {
        alert("hi");
    }
});

new foo();

我希望这是有道理的,我不是最擅长解释的人......

【讨论】:

  • 啊,那是我的第一次尝试,但是在您的示例中 data 变为静态,并且我需要 data 每个实例都是唯一的 testObj
  • 不用担心,您可以通过在构造函数中为每个实例的对象存储本身命名空间或使用模式 #2 来进行遮挡 - 任您选择。
  • 谢谢!!!后一种模式非常适合我。如果你有时间,我希望你能帮助我更好地理解你的方法。你的闭包有点不同,而不是函数定义末尾的})();,你有});并声明new new testObj();为什么这个“实例化”var data而不是创建一个私有静态变量?另外,有没有办法在这个闭包中创建一个私有静态函数,或者像data这样的函数会存在于每个testObj实例的内存中吗?
  • 另外,更优雅:gist.github.com/855443 以及 mutators 现在如何工作:github.com/mootools/mootools-more/blob/master/Source/Class/…
  • 完美!再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 2013-06-13
  • 1970-01-01
  • 2014-06-19
  • 1970-01-01
相关资源
最近更新 更多