【问题标题】:Flaws with the following implementation of private state of instance objects以下实例对象私有状态实现的缺陷
【发布时间】:2014-10-15 22:06:16
【问题描述】:

我已经阅读过,通常不建议使用实例对象的私有状态,如果能帮助我指出以下实现的缺陷/缺点,我将不胜感激。 非常感谢任何建议/批评。

var namespace = {};

namespace.parent = {
    parent_method1 : function () {},
    parent_method2 : function () {}
};


namespace.child = function (properties) {

    var private="secret"; 

        this.prototype = {
        create : function () {
            this.unique = 'base';
            this.unique += this.properties;
                    return this.unique;
        },
            get_private: function () {
                console.log(private);
            },
            set_private: function (val) {
                private = val;
            }
        };


    var proto = Object.create(namespace.parent);
    var instance = Object.create(proto);
    for (var property in this.prototype) {
            if (this.prototype.hasOwnProperty(property)) {
                proto[property] = this.prototype[property];
            }
    }   
        instance.properties = properties;
    return instance;  
};

var a = namespace.child("a");
console.log(a.create());
a.get_private();
a.set_private("new_a_secret");
a.get_private();

var b = namespace.child("b");
console.log(b.create());
b.get_private();
a.get_private();

【问题讨论】:

    标签: javascript inheritance design-patterns private-members


    【解决方案1】:

    如果能帮助我指出以下实现的缺陷/不足,我将不胜感激。

    我认为您对 var private 的实现没有任何问题,前提是它可以按照您的预期进行。

    但是,代码的最大缺陷是:我看不懂。你的实现应该做什么?它不遵循任何标准模式。这可能是伪方法的一个缺点,在实现真实世界模型时会被清除;但是,就目前而言,这很令人困惑。一些文档 cmets 也会有所帮助。

    具体来说:

    • namespace.child 有什么作用?它看起来像一个工厂函数,但我不确定它会产生什么“孩子”。
    • 此外,由于某种原因,它确实在每次调用时将namespace.prototype 属性设置为一个新对象,然后将其混合到instance 对象 proto 对象中。但是,它会将最后创建的实例的内部结构(get_privateset_private)留在全局范围内。
    • ab 应该是类吗?为什么他们有 .create() 方法,初始化类(实例?) - 如果有的话,应该被称为 .init()?为什么他们返回 .unique 属性值?
    • 为什么child 方法不立即初始化那些被分解的对象?
    • 保存字符串值的 .properties 字段是什么?
    • 为什么要对那些instance 对象使用两级继承? Object.create(namespace.parent) 可以理解,它继承自一个共享的静态对象。但是为什么然后使用Object.create(proto),复制proto上的一些属性(createget_privateset_private)和instance上的一些属性(propertiesunique)?为什么要区分它们?

    【讨论】:

    • 好吧,那就不行了,因为ab 都不能实例化。
    • namespace.child 应该是一个生产类的工厂函数; init() 是命名初始化函数的更好方法 .unique 用于(令人困惑?)表明它们返回基于 .properties 的唯一内容 - 存储字符串只是一个示例。 get_private、set_private 和 create(well init) 应该在每个类实例之间共享,(包括 parent_method1 和 parent_method2)是否有更好的方法让它们全部针对分解的类共享,可能在你建议的一个继承级别下?
    • 问题在于create(或init)实际上初始化了类本身,而不是创建类的实例。您的术语“在每个类实例之间共享​​>”有歧义,您是指类对象还是实例对象?
    • 感谢 Bergi,我的意思是 this.prototype 方法要在工厂出来的每个孩子之间共享。与添加另一个继承级别相比,将 this.prototype 方法应用于实例对象就足够了吗?抱歉让您感到困惑,我是这方面的新手。
    • 不,它们不是——每次调用.child() 都会使用自己的方法创建一个新的.prototype 对象。只有namespace.parent 的属性在它们之间共享。请注意,共享它们意味着a.set_private(…) 会影响b.get_private()(目前没有,如您的演示中所见,所以我认为这是意料之中的)
    猜你喜欢
    • 1970-01-01
    • 2012-11-21
    • 2016-09-19
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多