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(){...}
}
  1. 是一个命名构造函数。
  2. 将与 instanceof Person
  3. 一起正常工作
  4. 使用
  5. 进行混合或经典 Javascript 继承更容易
  6. 如果有很多方法,可以将原型用于可能消耗更少内存或更快构造对象的方法
  7. 也可以设计为无需 new
  8. 即可工作
  9. 更类似于新的 ES6 classextends 语法的工作方式,这很可能是将来会编写很多 Javascript 的方式。

第二个:

function Person(age,name){
    var p = {}
    p.name = name;
    p.age = age;
    p.speak = function(){...}
    return p;
}
  1. 是一个工厂函数。它创建一个通用对象,为其分配属性,然后 return 对象。
  2. 它可以继承自,但不能以经典方式仅由另一个知道该对象如何工作的工厂函数继承。某些类型的 mixin 继承不适用于此结构。
  3. 不适用于 instanceof
  4. 不会也不能将原型用于方法。
  5. 可以用 new 调用并且仍然有效(系统创建的新对象将被丢弃)。
  6. 可以创建任何类型的对象。它甚至可以根据传递的参数或环境进行分支,并根据某些逻辑创建不同类型的对象。从技术上讲,您也可以使用第一种样式来执行此操作,但效率很低,因为解释器会创建特定类型的对象,然后您会 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

Factory constructor pattern

Some Useful JavaScript Object Creation Patterns

Constructors Are Bad For JavaScript

Constructors vs factories