JavaScript 对象属性与原型链机制详解

作者:代码拾荒

时间:2026-10-21

浏览:480

本文详细解析 JavaScript 中 Native Object 与 Host Object 的区别,重点阐述对象属性(property)的动态创建与赋值机制。通过代码示例说明属性读取时原型链(prototype chain)的查找规则,以及写入操作对原型链的影响,揭示对象属性与原型之间的核心关系。

文章目录

JavaScript 对象类型概述

ECMAScript 规范定义了两种主要对象类型:Native Object(原生对象)属于语言核心范畴,而 Host Object(宿主对象)则由运行环境提供,例如 document 对象。


Dom Node 等宿主对象也属于此类。


原生对象具有松散的结构,支持动态添加属性(property)。每个属性包含一个名称和一个值,该值可以是另一个对象的引用。


或者为内置数据类型,包括 String、Number、Boolean、Null 或 Undefined。


以下示例展示了 JavaScript 对象如何设置和读取属性值。



对象属性的创建与赋值

赋值操作


创建对象属性非常直接,只需通过赋值操作即可完成。


代码



1. var objectRef = new Object(); //create a generic javascript object.




可以通过以下方式创建名为 testNumber 的属性。


代码



1. objectRef.testNumber = 5;


2. /* - or:- */


3. objectRef["testNumber"] = 5;




如果属性名称已存在,赋值操作不会重新创建该属性,而是直接更新其值。


代码



1. objectRef.testNumber = 8;


2. /* - or:- */


3. objectRef["testNumber"] = 8;





对象的原型(prototype)本身也是一个对象,可以拥有属性(property)。对原型属性的赋值操作与普通对象属性创建无异。


没什么不同。



属性取值与原型链机制

取值操作


在取值操作中,property 和 prototype 的行为有所不同。首先看最简单的 property 取值操作。


代码



1. /*为一个对象的属性赋值,如果这个对象没有这个属性,那么在赋值操作后,这个对象就有这个属性了 */


2. objectRef.testNumber = 8;


3. /* 读出这个属性的值 */


4. var val = objectRef.testNumber;


5.


6. /* 现在val 就得到了刚才赋予objectRef的值8了*/




prototype 揭密



所有对象都可以拥有 prototypes,而 prototypes 本身也是对象,因此也可以拥有自己的 prototypes。这种循环引用形成了原型链(prototype chain)。


当链中指向的 prototype 为 null 时,链终止(Object 的默认 prototype 是 null)。


代码



1. var objectRef = new Object(); //create a generic javascript object.




创建一个新的 JS 对象时,其 prototype 为 Null。因此,objectRef 的原型链仅包含 Object.prototype。


接下来看下面的代码。


代码



1. /* 构建MyObject1这个类型的构造函数


2. MyObject1 - type.


3. */


4. function MyObject1(formalParameter){


5. /* 为者对象创建一个属性名字叫testNumber


6. */


7. this.testNumber = formalParameter;


8. }


9.


10. /* 构建MyObject2这个类型的构造函数


11. MyObject2 - type:-


12. */


13. function MyObject2(formalParameter){


14. /* 为者对象创建一个属性名字叫testString*/


15. this.testString = formalParameter;


16. }


17.


18. /* 下一步的操作会用MyObject1对象替换掉MyObject2默认的prototype属性*/


19. MyObject2.prototype = new MyObject1( 8 );


20.


21. /* 最后我们创建MyObject2类型的一个对象*/


22.


23. var objectRef = new MyObject2( "String_Value" );




objectRef 是 MyObject2 类型的对象,拥有一个原型链。链中的第一个对象是 MyObject1 对象,该对象也有 prototype,即 Object 默认的 prototype。Object.prototype 的 prototype 为 null,至此原型链结束。


这个prototype是Object默认的prototype,Object.prototype的prototype是null,至此这条prototype链结束。


当发生取值操作时,objectRef 的整个原型链开始工作。


代码



1. var val = objectRef.testString;




objectRef 对象有一个名为 testString 的属性,该代码将 testString 的值赋给 val。


代码



1. var val = objectRef.testNumber;




在 objectRef 对象中并没有 testNumber 这个属性,但 val 却得到了值 8,而不是 undefined。这是因为解释器在当前对象未找到目标属性后,会检查该对象的 prototype。objectRef 的 prototype 是 MyObject1 对象,该对象拥有 testNumber 属性,因此 val 得到值 8。


访问属性后,就会去检查这个对象的prototype,objectRef的prototype是MyObject1对象,这个对象有testNumber这个属性,所以val得到8这个值。


代码



1. var val = objectRef.toString;




现在 val 是一个函数引用,该函数是 Object.prototype 的 property。由于 MyObject1 和 MyObject2 均未定义 toString 属性,因此返回 Object.prototype。


所以Object.prototype返回。


代码



1. var val = objectRef.madeUpProperty;




最后 val 是 undefined,因为 MyObject1、MyObject2 和 Object 均未定义 madeUpProperty 属性,因此得到的是 undefined。



读写操作对原型链的影响

读操作会读取在obj自己和prototype 链上发现的第一个同名属性值


写操作会为obj对象本身创建一个同名属性(如果这个属性名不存在


这意味着 objectRef.testNumber = 3 会在 objectRef 对象上创建一个名为 testNumber 的 property。当下一次读取 testNumber 时,原型链将不再工作,仅返回 objectRef 的 property 值 3,而 MyObject1 的 testNumber 属性不会被修改。以下代码可以验证。


这就意味着objectRef.testNumber = 3会在objectRef对象上创建一个property,名字是testNumber,当下一次在要读取testNumber时


代码



1. /* 构建MyObject1这个类型的构造函数


2. MyObject1 - type.


3. */


4. function MyObject1(formalParameter){


5. /* 为者对象创建一个属性名字叫testNumber


6. */


7. this.testNumber = formalParameter;


8. }


9.


10. /* 构建MyObject2这个类型的构造函数


11. MyObject2 - type:-


12. */


13. function MyObject2(formalParameter){


14. /* 为者对象创建一个属性名字叫testString*/


15. this.testString = formalParameter;


16. }


17.


18. /* 下一步的操作会用MyObject1对象替换掉MyObject2默认的prototype属性*/


19. var obj1 = new MyObject1( 8 );


20. MyObject2.prototype = obj1;


21.


22. /* 最后我们创建MyObject2类型的一个对象*/


23.


24. var objectRef = new MyObject2( "String_Value" );


25.


26. alert(objectRef.testNumber);


27. objectRef.testNumber = 5;


28. alert(objectRef.testNumber);


29. alert(obj1.testNumber);

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章