Javascript中构造对象的两种方式

Posted

技术标签:

【中文标题】Javascript中构造对象的两种方式【英文标题】:Two ways of constructing an object in Javascript 【发布时间】:2015-06-06 20:59:55 【问题描述】:
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()...

第二个返回一个对象,所以你可以写

Person(12,"mark")

而不是

new Person(12,"mark")

所以我想我的问题是,使用第二个版本有什么问题吗?我所说的差异是否正确?它们是两者之间的唯一差异吗?

【问题讨论】:

Constructor function vs Factory functions的可能重复 @Qantas94Heavy - 这个问题是在问一些其他问题中没有问或回答的问题。在我看来,这不是一个纯粹的重复,尽管显然相关。 【参考方案1】:

第一个:

function Person(age,name)
    this.name = name;
    this.age  = age;
    this.speak = function()...

    是一个命名的构造函数。 将与instanceof Person 正常工作 使用 mixins 或经典 javascript 继承更容易 如果有很多方法,可以将原型用于可能消耗更少内存或更快构造对象的方法 也可以设计为无需 new 即可工作。 更类似于新的 ES6 classextends 语法的工作方式,这可能是未来编写大量 Javascript 的方式。

第二个:

function Person(age,name)
    var p = 
    p.name = name;
    p.age = age;
    p.speak = function()...
    return p;

    是一个工厂函数。它创建一个通用对象,为其分配属性,然后返回该对象。 它可以从知道该对象如何工作的另一个工厂函数继承,但不能以经典方式继承。某些类型的 mixin 继承不适用于这种结构。 不适用于instanceof。 没有也不能将原型用于方法。 可以使用new 调用并且仍然可以工作(系统创建的新对象将被丢弃)。 可以创建任何类型的对象。它甚至可以根据传递的参数或环境进行分支,并根据某些逻辑创建不同类型的对象。从技术上讲,您也可以使用第一种样式来执行此操作,但是效率低下,因为解释器创建了特定类型的对象,然后您将返回其他内容,从而导致创建的原始对象随后被垃圾回收。因此,如果您要创建多种不同类型的对象,则第二种方法会更有效。

除了这些差异之外,两者的功能基本相同,并且任何一种方法在技术上都没有“错误”。

在 Javascript 中两种编程风格都有拥护者,有些人会说在某些情况下一种比另一种更合适,反之亦然。我建议你为这个对象构建几个子类,以消除更多的编程差异,因为子类的工作方式也不同。


如果您想搜索有关该主题的其他文章,这基本上是“构造函数与 Javascript 中的工厂函数”,有时会误入支持/反对使用 .prototype 的论点,但也倾向于也涵盖您的主题。

以下是关于该特定主题的一些文章(涵盖各种观点):

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

【讨论】:

以上是关于Javascript中构造对象的两种方式的主要内容,如果未能解决你的问题,请参考以下文章

js中构造函数的原型添加成员的两种方式

18.2 实现线程的两种方式

Java线程Thread使用匿名内部类创建的两种方式

JavaScript对象属性访问的两种方式

在堆栈上声明对象的两种方式之间的区别

javascript消除字符串两边空格的两种方式,面向对象和函数式编程