javascript - Kyle Simpson 的 OLOO 在 Object.create 之后添加多个属性

标签 javascript inheritance model delegation

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

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”的所有调用委托(delegate)给“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);

这正确地创建了 Bar 对象,并创建了 someAdditionFunc 和 someAdditionalProp 属性,但它们都设置为“未定义”。我认为这是正确的行为,但我想知道我是否坚持使用 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

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

最佳答案

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

Object.setPrototypeOf() (ES6)

因为这是在 ES6 中,所以只有当您使用 JavaScript 引擎已知的服务器端代码时,它才真正有用,否则您将不得不进行填充。请参阅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 对象所示,对象属性描述符的默认值几乎总是不是您想要的,因此它最终会变得非常冗长,甚至更多乏味。

关于javascript - Kyle Simpson 的 OLOO 在 Object.create 之后添加多个属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30716944/

相关文章:

javascript - jQuery:选择默认值并触发多个选择的更改

php - Illuminate\Database\Eloquent\Builder 类的对象无法转换为字符串

javascript - 用javascript替换html中的javascript代码

javascript - Google 甘特图显示错误的年份

以派生类为参数的 C++ 基类构造函数(?)

子类的 C++ 静态成员修饰符

Django,用具有最低参数的多对多字段元素的id注释字段

ruby-on-rails - rails ,设计 : unknown attribute 'password' for User

JavaScript 条件语句未按预期工作

java - 从类和接口(interface)重新继承静态字段