用于初始化对象的编码模式 - 构造函数(新)与 Object.create()(Crockford)
Coding patterns for initializing objects - constructors (new) vs. Object.create() (Crockford)
注意:这不是一个关于经典和原型继承的问题。这是关于使用什么编码模式来初始化对象。类构造函数创建和初始化对象,而避免使用new
运算符并采用Object.create()
只会创建对象并设置原型链。我还没有找到一个在线资源来解释在采用 Crockford Object.create()
方法时进行创建和初始化的最佳实践编码模式。
如果我有一个构造函数(在我的脑海中,这让我的类,尽管我知道类在主流 JavaScript 中在技术上还不存在)
function Person(first, last) {
this.name = {
first: first,
last: last
};
}
Person.prototype.tellName = function() {
return this.name.first + ' ' + this.name.last;
}
然后我可以像这样实例化它
var p1 = new Person('John', 'Doe');
var p2 = new Person('Sven', 'Svensson');
并分别更改Person.name.first
和Person.name.last
p1.tellName(); // Output: 'John Doe'
p2.tellName(); // Output: 'Sven Svensson'
p1.name.first = 'Peter';
p2.name.last = 'Celery';
并使用以下输出Person.tellName()
执行对象的函数
p1.tellName(); // Output: 'Peter Doe'
p2.tellName(); // Output: 'Sven Celery'
这与我在C++或Java中构建此类类的方式非常相似。
当使用 Crockford (Object.create()
-ish) 方法而不是 new
时,我使用什么模式来构造或启动一个对象,我可以在其中分配给嵌套对象?
例如
...
// some code that does the same stuff as defining a class + constructor
...
var p1 = ???????
var p2 = ???????
// The following is the code and behavior I'm looking to get
p1.tellName(); // Output: 'John Doe'
p2.tellName(); // Output: 'Sven Svensson'
p1.name.first = 'Peter';
p2.name.last = 'Celery';
p1.tellName(); // Output: 'Peter Doe'
p2.tellName(); // Output: 'Sven Celery'
而不是:
function Person(first, last) {
this.name = {
first: first,
last: last
};
}
Person.prototype.tellName = function() {
return this.name.first + ' ' + this.name.last;
}
你只需要:
function Person(first, last) {
return {
name: { first: first, last: last },
tellName: function() { return this.name.first + ' ' + this.name.last; }
};
};
或者,如果您更喜欢person.create()
的外观,那么:
var person = {
create: function(first, last) {
return {
name: { first: first, last: last },
tellName: function() { return this.name.first + ' ' + this.name.last; }
};
}
};
但在第二种情况下,你会有一个不必要的对象(person
),只包含一个函数(person.create()
)。
不需要Object.create
也不需要new
因为这些是为了继承,你说你不在乎。这将允许您执行以下操作:
var p1 = Person('John', 'Doe');
var p2 = Person('Sven', 'Svensson');
一个有趣的事实是,如果您愿意,您仍然可以以这种方式在person.create
面前使用new
,但它不会提供任何效果。如果必须使用现有函数,则可以使用 .call
显式设置this
上下文
// with your original `Person`
var p1 = Person.call({}, 'John', 'Doe');
var p2 = Person.call({}, 'Sven', 'Svensson');
这也不会设置原型,因为函数不像构造函数那样调用。请参阅此答案,了解原型答案的作用和不作用 - 在一行中,它是关于共享功能,而不是关于构造对象的属性。
相关文章:
- 函数未在Object.keys或Object.getOwnPropertyNames下列出,但可以调用
- delete在Object上效率低下,但在DOM Element's的数据属性,与null out相比
- 有没有一种方法可以列出Ember.Object的所有绑定
- 如何取消object.prototypes javascript的一个函数
- 为什么是文档.旧版应用程序中的DOM-object.properties为null
- 将*.js文件的内容放入Object中
- Object.prototype using 'this'
- 使用Object.create()的角度服务继承
- 如何使用object.assign()从其他对象引用基本对象属性
- 循环的数组推入在Object容器中具有不同的值
- reducers在redux中得到Function not Object,what'it’他错了
- JSON.stringify和Object.keys在同一个对象上产生不同的结果
- 在使用object.create创建的对象中使用super
- Join架构验证:Join.object定义数组中的有效键
- jquery打印[object XMLDocument]而不是文件内容
- ExtJS 4 Object.prototype fail
- JavaScript-从对象数组中输出随机OBJECT
- 为什么“{}+1”在Chrome和Firefox中排名第一,而字符串'[object object]1'
- 什么是“;原型;通过JavaScript中的Object Literal Notation创建的对象的链接
- 用于初始化对象的编码模式 - 构造函数(新)与 Object.create()(Crockford)