在javascript中创建对象的两种方法
Posted
技术标签:
【中文标题】在javascript中创建对象的两种方法【英文标题】:two ways of creating object in javascript 【发布时间】:2011-10-03 06:30:26 【问题描述】:我正在通过以下方式创建 javascript 对象:
function field(name,label)
this.name = name
this.label= label;
var a = new field("market","Mkt").
然后我将 a 分配给另一个对象。
object.newField = a;
第二种方式是直接新建一个属性
object.2ndNewField =
name: "market2",
label:"Mkt2"
我尝试在其他函数中读取对象。它们的行为不同,但是,当我对对象进行字符串化时,它看起来还不错。我创建的两个属性有什么区别?
顺便说一句,下面的对象有什么不同吗?
object.2ndNewField =
"name": "market2",
"label":"Mkt2
【问题讨论】:
这两个对象的行为有何不同? 【参考方案1】:对于第一个选项...远离使用“新”。如果“new”被错误地使用,或者在应该使用时被省略,你可能会严重影响你的全局命名空间。另外,您必须小心在代码中的某些地方使用“this”,因为它可能会绑定到您认为不正确的东西,甚至绑定到您的全局数据。
在您提供的第二个选项中,您可以安全地将其用于仅用作数据/方法集合的对象(即不是“类类”行为)。如果您想要一些可以使用私有和公共变量/方法创建多个实例并且可以从中继承的东西,那么您应该使用返回对象的函数。
我写了一篇关于如何安全地创建基础对象和使用继承的示例here。如果您点击链接,您会明白为什么我没有在这篇文章中重新输入所有内容;)。
希望这会有所帮助...
【讨论】:
呃.....“远离......新”......“不良影响......命名空间”?我不明白。new
根本不影响命名空间。同样使用new
“错误”或省略并不比任何其他语义上无效的代码更严重。
@pst,如果您在 JavaScript 中定义了一个类似“类”的对象,该对象打算使用“new”,并且在初始化新对象时忘记使用“new”运算符......” this" 绑定到全局对象,而不是类对象。这可能会导致与全局数据发生变量冲突的许多问题。因此,如果您在创建新对象时忘记调用 new,您可以在不知情的情况下影响代码的其他区域,并且不会报错。通常最好使用从函数返回的对象...尤其是在您编写 API 时
1) 没有类 ;-) 2) 忘记指定 new
与任何其他语义错误没有什么不同 -- 这是代码中的错误,必须修复并且因此不是唯一的(在函数中没有return
,它在尝试使用新对象时很容易检测到,因为函数的结果将是undefined
)3)@987654327 @ 是使用 [[prototype]]
链所必需的,因为 [不幸] 缺乏指定创建后原型的能力。
@pst,我知道没有类,提示引号。虽然它们是对象而不是类,但对于受过经典训练的程序员(大多数程序员)来说,更容易将它们描述为类。是的,忘记指定new
在技术上是语义,是的,您必须使用new
才能使用原型对象。如果您不打算使用原型类型继承模式,则不需要[[prototype]]
。作为一名 API 编写者,我更喜欢闭包,因为用户搞砸的方式似乎更少……但你是对的,这都是语义【参考方案2】:
不同的是,在第一种情况下,创建的对象继承自field.prototype然后Object.prototype(即其内部[[Prototype]]是field.prototype)。原型,其内部 [[Prototype]] 是 Object.prototype),而在第二种情况下,它仅继承自 Object.prototype。
另一种看待它的方式是:
object.newField instanceof field; // true
object.newField instanceof Object; // true
object.newField2 instanceof field; // false
object.newField2 instanceof Object; // true
或者继承链是:
object.newField -> field.prototype -> Object.prototype -> null
object.newField2 -> Object.prototype -> null
其中 '->' 表示“继承自”。
【讨论】:
我正在尝试在另一个函数中遍历对象,field.prototype 使它无法按预期工作。有什么办法可以解决吗? @CKevenfunction F () ; F.prototype = hello: "world"; var f = new F(); alert(f.hello);
f 中的对象具有 [[prototype]]
但没有 prototype
属性(某些浏览器将其公开为 __proto__
属性或类似属性)。构造函数F
有一个prototype
属性,用作新对象[[prototype]]
的基础。
@CKeven 至少 FF 支持新对象的 constructor
属性,但我不知道规范对此有何规定。请注意,构造函数prototype
在new
时应用于新对象——稍后将新对象分配给prototype
对先前创建的对象没有影响(但原型对象可以改变,这将当然是共享的)。
@pst - 在 ECMA-262 中,所有内置原型都有一个公共构造函数属性,该属性指向它们相关的内置构造函数,例如Array.prototype.constructor === Array
。如果您使用不同的构造函数(即您自己编写的构造函数)创建原型链,则可以手动将公共 constructor 属性设置为“正确”的构造函数对象,否则它们将指向 Function 或 Object 或其他.以上是关于在javascript中创建对象的两种方法的主要内容,如果未能解决你的问题,请参考以下文章