【问题标题】:Kyle Simpsons's OLOO adding Multiple properties after Object.createKyle Simpsons 的 OLOO 在 Object.create 之后添加了多个属性
【发布时间】:2015-08-23 09:07:02
【问题描述】:

我最近刚刚了解了 Kyle Simpson 创造的“OLOO”委托模型(而不是继承),他开始使用类似于下面的代码 sn-p 创建对象并委托属性和函数:

var Foo = {
    init: function(who) {
        this.me = who;
    },
    identify: function() {
        return "I am " + this.me;
    }
};

var Bar = Object.create(Foo);

Bar.speak = function() {
    alert("Hello, " + this.identify() + ".");
};

var b1 = Object.create(Bar);
b1.init("b1");
var b2 = Object.create(Bar);
b2.init("b2");

b1.speak(); // alerts: "Hello, I am b1."
b2.speak(); // alerts: "Hello, I am b2."

在这里,Bar 将所有对“init”和“identify”的调用委托给“Foo”对象,但是在创建 Bar 之后,我们必须逐行执行并通过以下方式向 Bar 添加任何其他属性:

Bar.someAdditionalFunc = function(){ /* Do something else for Bar */ };
Bar.someAdditionalProp = { prop: 'Value' };

我的问题是:有没有什么方法可以为(可能的)大 Bar 预定义(或后定义)所有这些属性,而不为每个新属性使用点表示法 (Bar.PropertyName = ...) ?

例如,我正在考虑做这样的事情:

var BarTemp = {
    someAdditionalFunc: function(){ /* Do something else for Bar */ },
    someAdditionProp: { prop: 'Value' }
};

var Bar = Object.create(Foo, BarTemp);

这正确地创建了带有 someAdditionFunc 和 someAdditionalProp 属性的 Bar 对象,但它们都设置为“未定义”。我想这是正确的行为,但我想知道我是坚持使用 jQuery.extend() 还是像这样创建另一个子对象:

var subObject = {
    someAdditionalFunc: function() {},
    someAdditionalProp: { prop: 'value' }
    // ... all other properties we want to add
}

var Bar = Object.create(Foo);
Bar.otherStuff = subObject; 
// Now I always have to reference those properties by:
//    Bar.otherStuff.someAdditionalFunc
// instead of:
//    Bar.someAdditionalFunc

或者有没有更简单的方法来实现/考虑这个?

【问题讨论】:

    标签: javascript inheritance model delegation


    【解决方案1】:

    有几个选项可以通过更少的步骤完成此操作,但这实际上取决于您的浏览器支持要求。第二个选项也不是特别“简单”!

    Object.setPrototypeOf() (ES6)

    因为这是在 ES6 中,所以只有在您使用已知 JavaScript 引擎的服务器端代码时它才真正有用,否则您将不得不进行 polyfill。见compatability chart here.

    var foo = {
      bar: function() { console.log("bar"); }
    }
    
    var baz = {
      someProp: 'a',
      someFunc: function () { console.log("dork"); }
    }
    
    
    Object.setPrototypeOf( baz, foo );
    baz.someFunc() // "dork"
    baz.bar()      // "bar"
    

    Object.create( proto , propertiesObject ) (ES5)

    这得到了更广泛的支持,但仍可能会导致您在使用旧版本的 IE 时出现问题。

    基本上,您的问题几乎就在那里,只是您需要使用 property descriptors 而不仅仅是属性和值的哈希:

    var foo = {
      bar: function() { console.log("bar"); }
    }
    
    var b = Object.create( foo, {
      baz: {
        value: function() { console.log("baz") },
        writable: true,      // default: false
        enumerable: true,   // default: false
        configurable: true,  // default: false
      },
      defProps: {
        value: function() { console.log("default"); }
      }
    });
    
    b.bar();      // bar
    b.baz();      // baz
    b.defProps(); // default
    
    for(var prop in b){
     console.log(prop); // baz, bar
    }
    
    delete b.defProps;   //typeError
    b.defProps = "test"; //typeError
    

    问题在于,如上面的 defProps 对象所示,对象属性描述符的默认值几乎总是不是您想要的,因此最终会变得非常冗长甚至乏味。

    【讨论】:

    • 这已经很晚了,但是感谢 Ed!我想知道 ES6 版本是否会与类的引入相关,但 ES5 版本正是我想要的!
    猜你喜欢
    • 2015-06-29
    • 2017-08-04
    • 1970-01-01
    • 2017-04-23
    • 2017-05-31
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多