JavaScript: attribute assignment and prototype chain

Source: Internet
Author: User
Tags hasownproperty

This article will study how the prototype chain of an object affects the attribute assignment operation of the object. this article elaborates in detail a knowledge point mentioned in the previous article "[translation] attributes in JavaScript: The difference between definition and value assignment.

Prototype chain

Each object has a prototype chain that contains one or more objects. This object is the starting object of this prototype chain. all attributes of all objects in the prototype chain can be accessed by this object. for example:

 
 
  1. > var proto = { foo: 1 };  
  2. > var obj = { __proto__: proto, bar: 2 };  
  3. > obj.foo  
  4. 1  
  5. > obj.bar  

We used the special attribute _ proto _ to create the prototype chain (this property is not widely supported by all browsers ). the prototype chain of Object obj contains three objects: obj at the beginning, followed by proto, and Object at the end. prototype. object. prototype is the prototype Object of the Object constructor. Most prototype chains contain it (most, but not all ):

 
 
  1. > Object.prototype.isPrototypeOf({})  
  2. true 
  3. > Object.prototype.isPrototypeOf([])  
  4. true 
  5. > Object.prototype.isPrototypeOf(new Date())  
  6. true 

And it is the end object of the prototype chain:

 
 
  1. > Object.getPrototypeOf(Object.prototype)  
  2. null 

Many standard methods of common objects are inherited from Object. prototype, such as toString () and hasOwnProperty ().

Assign values to attributes

If you assign a value to an attribute, you can only modify the starting object (that is, the object itself) on the prototype chain. If your attributes already exist, you can change the value of this attribute. Otherwise, create this new property:

 
 
  1. > obj.foo = 3;  
  2. > obj.foo  
  3. 3  
  4. > obj.hasOwnProperty("foo")  
  5. true 
  6. > proto.foo  

The purpose of this design is that a prototype can introduce a common initial value (the value of the inherited attribute) to all its instances ). if you assign a value to the attribute of the same name for one instance to change the public attribute value on the prototype, the initial values of all instances will be changed. to prevent this, you can also modify the initial values of a single instance. The attribute assignment Operation is designed to only allow you to change the values of an existing attribute. if this attribute does not exist, it is automatically created and assigned a value.

Accessors and prototype links

An accessor attribute that exists on the prototype chain [3] can block "creating attributes of the same name on the starting object of the prototype chain ". assume that object obj inherits an object with getter and setter:

 
 
  1. var obj = {  
  2.     __proto__: {  
  3.         get foo() {  
  4.             return 1;  
  5.         },  
  6.         set foo(x) {  
  7.             console.log("Setter called: "+x);  
  8.         }  
  9.     }  
  10. };  

If you assign a value to the property foo of object obj, it will call the setter accessor on its prototype, instead of creating its own property foo for obj. Similarly, if you read the foo attribute of object obj, it will also call the getter accessors on its prototype:

 
 
  1. > obj.foo = 2;  
  2. Setter called: 2  
  3. > obj.foo  

If you want to disable the value assignment operation of this attribute (that is, read-only), you can disable setter:

 
 
  1. var obj = {  
  2.     __proto__: {  
  3.         get foo() {  
  4.             return 1;  
  5.         }  
  6.     }  
  7. };  
  8.  

In non-strict mode, such a value assignment operation will silently fail. In strict mode, an exception will be thrown:

 
 
  1. > (function () { "use strict"; obj.foo = 2; }());  
  2. TypeError: Cannot set property foo of obj which has only a getter 

Read-only attribute on the prototype chain

If the starting object on the prototype chain inherits a read-only attribute, you cannot change the value of this attribute by assigning values. For example, the following code:

 
 
  1. var proto = Object.defineProperty({},  
  2.     "foo",  
  3.     {  
  4.         value: 1,  
  5.         writable: false 
  6.     });  
  7. var obj = { __proto__: proto }; 

You cannot assign values to obj. foo:

 
 
  1. > (function () { "use strict"; obj.foo = 2; }());  
  2. TypeError: obj.foo is read-only 

This is exactly the same as the performance of the accessor attribute of only getter. this time, the prototype attributes can also be used as an initial shared value. The difference is that we should prevent a single instance from changing its own initial value. if you want to create a property foo for obj, you can use Object. defineProperty () and Object. defineProperties () to complete.

Http://www.2ality.com/2012/11/property-assignment-prototype-chain.html.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.