jjzjj

javascript - Javascript中构造对象的两种方式

coder 2024-07-30 原文

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")

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

最佳答案

第一个:

function Person(age,name){
    this.name = name;
    this.age  = age;
    this.speak = function(){...}
}
  1. 是一个命名的构造函数。
  2. 将与 instanceof Person 一起正常工作
  3. 使用 mixin 或经典的 Javascript 继承更容易
  4. 如果有很多方法,可以将原型(prototype)用于可能消耗更少内存或更快构造对象的方法
  5. 也可以设计为无需 new 即可工作。
  6. 更类似于新的 ES6 classextends 语法的工作方式,这很可能是 future 编写大量 Javascript 的方式。

第二个:

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

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

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 - Javascript中构造对象的两种方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29403919/

有关javascript - Javascript中构造对象的两种方式的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  6. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  7. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  8. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  9. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  10. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

随机推荐