使用Object.create()创建对象的模式
Object creation patterns using Object.create()
我一直在思考如何在使用Object.create()时进行多级继承,而不是传统的构造函数。我打开了一把小提琴。
我们有两种类型的对象,程序员和一个"子类"前端开发人员。程序员继承了程序员原型对象,正如你所看到的,所有的程序员都会很尴尬。
var programmerProto = Object.create(Object.prototype,{
beAwkward: {value: function(){
return "Yeah I uhh, AHEM, *shuffles feet*";
}
}
});
function programmerFactory (name, age, neckbeard){
return Object.create(programmerProto, {
name: {writable: true, enumerable: true, value: name},
age: {writable: false, enumerable: true, value: age},
neckbeard: {writable: true, enumerable: true, value: neckbeard}
});
}
现在对于前端开发人员来说,他们有自己的共同特点,所以我们需要一个新的原型对象。但是,前端开发人员也是程序员,因此我们将前端原型对象制作如下:
var frontEndProto = Object.create(programmerProto, {
beSmooth: {
value: function(){
return "Excuse me ma'am, could I interest you in a, fish sandwich?";
}
},
preferredLanguage: {writable: true, enumerable: true, value: 'JS'}
});
现在我们解决了问题。我想使用工厂方法来创建前端开发人员的实例,这样我就可以添加一些前端特定的属性,比如"CSS3_skillz"之类的。但是如果我使用Object.create(frontEndProto,"…"),那么。。。将是我已经在程序FactoryFunction中编写的所有代码。如果我从frontEndFactory中调用programmerFactory,那么返回对象的原型是programmerProto,而不是frontEndProto。处理这个问题的正确方法是什么?
我认为您在继承链和Object.defineProperty()
风格属性的使用上有点过分了。
除非您有充分的理由需要instanceof
之类的东西,否则您可以使用.extend()
函数来实现您的继承。我使用下面的下划线/lodash _.extend()
函数,但您几乎可以使用它的任何实现:
var programmerProto = {
beAwkward: function(){
return "Yeah I uhh, AHEM, *shuffles feet*";
}
};
function programmerFactory (name, age, neckbeard){
return _.extend({
name: name,
age: age,
neckbeard: neckbeard
}, programmerProto);
}
var frontEndProto = {
beSmooth: function(){
return "Excuse me ma'am, could I interest you in a, fish sandwich?";
},
preferredLanguage: 'JS'
};
function frontEndFactory(name, age, css3Skillz) {
return _.extend(programmerFactory(name, age, true), {
css3Skillz: css3Skills
}, frontEndProto);
}
我认为这次关于这个主题的演讲非常好:
http://www.youtube.com/watch?v=PV_cFx29Xz0&t=28m57s
解决问题的方法是将一个对象的属性附加到另一个对象。
首先,我使用的附加函数-
var appendObject = function(obj, toAppend) {
Object.keys(toAppend).forEach(function(el) {
Object.defineProperty(obj, el, Object.getOwnPropertyDescriptor(toAppend,el));
});
return obj;
}
这样做非常简单——它遍历toAppend
的属性,并使用它们的属性描述符来定义obj
上的新属性。它正在变异obj
,但也会返回它,这样你就可以在需要的时候将其连锁
有了这个功能,你可以让他们的frontEndDevFactory像这样实现-
function frontEndDevFactory (name, age, pullupCount, rockStar){
var programmer = programmerFactory(name, age);
var newDev = Object.create(frontEndProto, {
pullupCount: {writable: true, enumerable: true, value: pullupCount},
rockStar: {writable: false, enumerable: true, value: rockStar}
});
appendObject(newDev, programmer);
return newDev;
}
这里有一个修改代码的小提琴来演示这一点。
- 在创建对象后附加一个jquery事件
- 错误:自动化服务器可以't创建对象
- 如何在不使用 new 关键字的情况下从函数创建对象
- 文本表示法VS.构造函数,用于在JavaScript中创建对象
- 创建对象函数原型和代码是错误的
- 使用Undercore创建对象集合
- 如何在JavaScript中创建对象时使用变量的值
- 正在创建对象的递归列表
- 这两种不同的创建对象文字的方法有什么区别
- ES6 const,用于在JavaScript中创建对象原型;这是一种模式吗
- 使用字符串作为名称创建对象
- 使用参数创建对象
- 如何在JS中创建对象的可变和不可变副本
- 用javascript创建对象的dynamic数组
- Javascript,用vars创建对象的最佳方法
- 离子幻灯片框中未创建对象
- 使用Object.create()创建对象的模式
- 使用模块模式时,如何创建对象的新实例
- 无法在严格模式下创建对象属性
- 创建模块模式的多个对象