Javascript中构造对象的两种方式
Two ways of constructing an object in Javascript
function Person(age,name){
this.name = name;
this.age = age;
this.speak = function(){...}
}
function Person(age,name){
var p = {}
p.name = name;
p.age = age;
p.speak = function(){...}
return p;
}
我看到的唯一区别是使用第一个必须用 new 调用让语言知道它构造一个新对象,它本质上只是构造一个对象,其中 'this' 指的是新对象正在创建??
即与此相同。
{
age: 12,
name: "mark",
speak: function(){...}
}
其中第二个 returns 一个对象,所以你可以只写
Person(12,"mark")
而不是
new Person(12,"mark")
所以我想我的问题是,使用第二个版本有什么问题吗?我所说的差异是否正确?它们是两者之间唯一的差异吗?
第一个:
function Person(age,name){
this.name = name;
this.age = age;
this.speak = function(){...}
}
- 是一个命名构造函数。
- 将与
instanceof Person
一起正常工作
- 使用
进行混合或经典 Javascript 继承更容易
- 如果有很多方法,可以将原型用于可能消耗更少内存或更快构造对象的方法
- 也可以设计为无需
new
。 即可工作
- 更类似于新的 ES6
class
和 extends
语法的工作方式,这很可能是将来会编写很多 Javascript 的方式。
第二个:
function Person(age,name){
var p = {}
p.name = name;
p.age = age;
p.speak = function(){...}
return p;
}
- 是一个工厂函数。它创建一个通用对象,为其分配属性,然后 return 对象。
- 它可以继承自,但不能以经典方式仅由另一个知道该对象如何工作的工厂函数继承。某些类型的 mixin 继承不适用于此结构。
- 不适用于
instanceof
。
- 不会也不能将原型用于方法。
- 可以用
new
调用并且仍然有效(系统创建的新对象将被丢弃)。
- 可以创建任何类型的对象。它甚至可以根据传递的参数或环境进行分支,并根据某些逻辑创建不同类型的对象。从技术上讲,您也可以使用第一种样式来执行此操作,但效率很低,因为解释器会创建特定类型的对象,然后您会 return 其他导致创建的原始对象随后被垃圾收集的对象。因此,如果您要创建多种不同类型的对象,第二种方法会更有效。
除了这些差异之外,两者的功能基本相同,并且两种方法在技术上都没有任何区别"wrong"。
Javascript 中两种编程风格都有拥护者,有些人会说有些情况下一种比另一种更合适,反之亦然。我建议您为此对象构建几个子类,以消除更多编程差异,因为子类的工作方式也不同。
如果您想搜索关于该主题的其他文章,这基本上是一篇 "constructor function vs. a factory function in Javascript",有时会误入使用 .prototype
的论点 for/against,但也倾向于也涵盖您的主题。
以下是关于该特定主题的一些文章(涵盖了各种观点):
JavaScript Constructor Functions Vs Factory Functions
Javascript object creation patterns
In defense of JavaScript’s constructors
Constructor function vs Factory functions
Some Useful JavaScript Object Creation Patterns
function Person(age,name){
this.name = name;
this.age = age;
this.speak = function(){...}
}
function Person(age,name){
var p = {}
p.name = name;
p.age = age;
p.speak = function(){...}
return p;
}
我看到的唯一区别是使用第一个必须用 new 调用让语言知道它构造一个新对象,它本质上只是构造一个对象,其中 'this' 指的是新对象正在创建??
即与此相同。
{
age: 12,
name: "mark",
speak: function(){...}
}
其中第二个 returns 一个对象,所以你可以只写
Person(12,"mark")
而不是
new Person(12,"mark")
所以我想我的问题是,使用第二个版本有什么问题吗?我所说的差异是否正确?它们是两者之间唯一的差异吗?
第一个:
function Person(age,name){
this.name = name;
this.age = age;
this.speak = function(){...}
}
- 是一个命名构造函数。
- 将与
instanceof Person
一起正常工作
- 使用 进行混合或经典 Javascript 继承更容易
- 如果有很多方法,可以将原型用于可能消耗更少内存或更快构造对象的方法
- 也可以设计为无需
new
。 即可工作
- 更类似于新的 ES6
class
和extends
语法的工作方式,这很可能是将来会编写很多 Javascript 的方式。
第二个:
function Person(age,name){
var p = {}
p.name = name;
p.age = age;
p.speak = function(){...}
return p;
}
- 是一个工厂函数。它创建一个通用对象,为其分配属性,然后 return 对象。
- 它可以继承自,但不能以经典方式仅由另一个知道该对象如何工作的工厂函数继承。某些类型的 mixin 继承不适用于此结构。
- 不适用于
instanceof
。 - 不会也不能将原型用于方法。
- 可以用
new
调用并且仍然有效(系统创建的新对象将被丢弃)。 - 可以创建任何类型的对象。它甚至可以根据传递的参数或环境进行分支,并根据某些逻辑创建不同类型的对象。从技术上讲,您也可以使用第一种样式来执行此操作,但效率很低,因为解释器会创建特定类型的对象,然后您会 return 其他导致创建的原始对象随后被垃圾收集的对象。因此,如果您要创建多种不同类型的对象,第二种方法会更有效。
除了这些差异之外,两者的功能基本相同,并且两种方法在技术上都没有任何区别"wrong"。
Javascript 中两种编程风格都有拥护者,有些人会说有些情况下一种比另一种更合适,反之亦然。我建议您为此对象构建几个子类,以消除更多编程差异,因为子类的工作方式也不同。
如果您想搜索关于该主题的其他文章,这基本上是一篇 "constructor function vs. a factory function in Javascript",有时会误入使用 .prototype
的论点 for/against,但也倾向于也涵盖您的主题。
以下是关于该特定主题的一些文章(涵盖了各种观点):
JavaScript Constructor Functions Vs Factory Functions
Javascript object creation patterns
In defense of JavaScript’s constructors
Constructor function vs Factory functions
Some Useful JavaScript Object Creation Patterns