注意:这不是关于经典继承和原型(prototype)继承的问题。它是关于使用什么编码模式来初始化对象。类构造函数创建和初始化对象,而避免使用 new
运算符并使用 Object.create()
仅创建对象并设置原型(prototype)链。我还没有找到解释在使用 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');
这也不会设置原型(prototype),因为函数不像构造函数那样被调用。参见 this answer关于原型(prototype)答案做什么和不做什么 - 总而言之,它是关于共享功能,而不是关于构建对象的属性。
关于javascript - 初始化对象的编码模式 - 构造函数(新)与 Object.create() (Crockford),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27858568/