Inheritance and prototype chains in JavaScript

Source: Internet
Author: User

Let's look at an example.

function User () {}var u1 = new User (); Console.log (u1.prototype);//Undefined Use object instance cannot access Prototypeconsole.log ( User.prototype);//{}, Access Prototypeconsole.log (u1.__proto__) using the constructor name,//{}, using the object instance to access the prototype pointer

This is the basic difference between __proto__ and prototype: It shows that the constructed object has no prototype property, each object is equivalent to a __proto__ pointer to its parent class, and a single-linked list in C is similar (image metaphor here)

Each function is created by default with a prototype property, which contains a constructor property, and a hidden property that points to object objects __proto__

1. The value of the constructor property is the object of the function

2. Called with new in front of a function, creates a new object that hides the prototype member of the function (linked by the __proto__ property), and the This of the function is bound to the new object.

The function always returns a value, returns undefined if no return value is specified, returns this if it is called as a constructor, and the return value is not an object, or if the return value is an object, it is meaningless as a constructor!

Defined

In terms of inheritance, each object in JavaScript has an internal private link pointing to another object, which is the prototype of the original object. The prototype object also has its own prototype until the object is prototyped null (that is, there is no prototype). This first-level chain structure is called the prototype chain .

While this is often referred to as one of the weaknesses of JavaScript, it is actually more powerful than the classic inheritance model. While it is quite trivial to build a classic model on a prototype model, it is more difficult to implement it in other ways.

Use different methods to create objects and build prototype chains use normal syntax to create objects
var o = {a:1};//O This object inherits all the properties above Object.prototype//So can use O.hasownproperty (' a ').//hasOwnProperty Is the property of Object.prototype itself. The Object.prototype prototype is null. The prototype chain is as follows://O---> Object.prototype---> Nullvar a = ["Yo", "whadup", "?"];/ /arrays are inherited from Array.prototype (IndexOf, foreach, and so on).//The prototype chain is as follows:/a---> Array.prototype---> Object.prototype--- > Nullfunction f () {  return 2;} Functions are inherited from Function.prototype (call, bind, and so on)://F---> Function.prototype---> Object.prototype---> Null

Creating objects using construction methods

In JavaScript, the construction method is actually a normal function. When you use the new operator to function, it can be called a construction method (constructor).

function Graph () {  this.vertexes = [];  This.edges = [];} Graph.prototype = {  Addvertex:function (v) {    This.vertexes.push (v);  }}; var g = new Graph ();//G is the generated object, his own attributes are ' vertexes ' and ' edges './/When G is instantiated, G.[[prototype]] points to graph.prototype.

Create an object using Object.create

A new approach has been introduced in ECMAScript 5: object.create. You can call this method to create a new object. The prototype of a new object is the create first parameter passed in when the method is called:

var a = {a:1}; A---> Object.prototype---> Nullvar b = object.create (a),//b---> A---> Object.prototype---> Nullcon Sole.log (B.A); 1 (inherited) var C = object.create (b);//c---> B---> A---> Object.prototype---> Nullvar d = object.create (nu ll);//D---> Nullconsole.log (d.hasownproperty); Undefined, because D did not inherit Object.prototype

1. Prototype chain

function declaration Functions person () {}//function expression var man = function () {}console.log (person.__proto__ = = = Function.prototype)//Truecons Ole.log (man.__proto__ = = = Function.prototype)//True Console.log (function.prototype.__proto__ = = = Object.prototype)/ /True Console.log (object.prototype.__proto__ = = = null)//trueobject.prototype.a = 1; Function.prototype.a =10;console.log (MAN.A); 10

From the above we can see the prototype chain

2, all constructors/functions of the __proto__ are pointing to Function.prototype

However, Math,json are present in the form of objects, without new. Their __proto__ are object.prototype.

3, all the constructors are from the Function.prototype

Includes the root constructor object and the function itself. All constructors inherit the properties and methods of the Function.prototype. such as length, call, apply, bind (ES5), Function.prototype is also the only one typeof Xxx.prototype as "Function" prototype. The prototype of other constructors is an object. As follows

There's one thing to figure out.

Console.log (typeof Object.prototype)//Object Console.log (object.__proto__ = = = Function.prototype)//True Console.log (function.prototype.__proto__ = = = Object.prototype)//Trueconsole.log (object.__proto__.__proto__=== Object.prototype)//Trueconsole.log (function.prototype.__proto__. __proto__=== null)//True

So the top-notch is object.prototype.__proto__ = = = NULL

4, the above said "all constructors/functions" of course, including the custom

5. P is an instance object of person, and the internal prototype of P always points to the prototype of its constructor person. Each object has a constructor property that can get its constructor, so the following print results are also identical

6, see a piece of code the original address http://segmentfault.com/q/1010000003791600/a-1020000003793415, about the difference between prototype and __proto__

简介:__proto__其实就是 [[prototype]]属性原本是不可用 js 访问的,后来(据说标准里又规定可以)firefox 和 chrome 中把这个属性命名为__proto__。后来ES又添加了函数getPrototypeof,这样就可以通过这个函数来访问这个属性,所以这个__proto__现在不是标准的一部分

Code One

<script type= "Text/javascript" >var animal = function () {};var dog = function () {};animal.price = 2000;dog.__proto__ = Animal;var tidy = new Dog (); Console.log (dog.__proto__ = = = Animal)//trueconsole.log (dog.__proto__.__proto__ = = = Animal . __proto__)//trueconsole.log (dog.__proto__.__proto__.__proto__  = = = Object.prototype)//trueconsole.log (dog._ _proto__.__proto__.__proto__.__proto__  = = = null)//trueconsole.log (tidy.__proto__  = = = Dog.prototype)// Trueconsole.log (tidy.__proto__.__proto__ = = = dog.prototype.__proto__)//trueconsole.log (tidy.__proto__.__proto__ = = = Object.prototype)//trueconsole.log (tidy.__proto__.__proto__.__proto__ = = = null)//trueconsole.log (dog.price)// 2000console.log (Tidy.price)//undefined</script>

Code two

<script type= "Text/javascript" >var animal = function () {};var dog = function () {};animal.price = 2000;dog.prototype = Animal;var tidy = new Dog (); Console.log (tidy.__proto__  = = = Dog.prototype)//trueconsole.log (tidy.__proto__.__ proto__  = = = animal.__proto__)//trueconsole.log (tidy.__proto__.__proto__.__proto__ = = = Object.prototype)// Trueconsole.log (tidy.__proto__.__proto__.__proto__.__proto__ = = = null)//trueconsole.log (dog.__proto__  = = = Function.prototype)//trueconsole.log (dog.__proto__.__proto__  = = = Object.prototype)//trueconsole.log (dog.__ proto__.__proto__.__proto__  = = = null)//trueconsole.log (dog.price)//undefinedconsole.log (Tidy.price)//2000 </script>

Summarize

1. All objects, including the prototype chain of the function object, eventually point to Object.prototype, and Object.prototype.__proto__===null, the prototype chain ends.
2, Animal.prototype is a common object.
3, object is a function object, is also the structure of functions, Object.prototype is a common object.
4, object.prototype.__type__ points to null.
5. Function.prototype is a function object, which says that the function object has a display prototype property, but Function.prototype has no prototype attribute, that is Function.prototype.prototype ===undefined, all Function.prototype function objects are a special case and have no prototype properties.
6, object is a function object, but Object.prototype does not point to Function.prototype, that is, Object.prototype!==function.prototype.

Prototype and constructor Relationship introduction

In JavaScript, each function object is named "Prototype" (The Function.prototype function object is an exception, there is no prototype property) and is used to refer to the prototype object. This prototype object is also known as the "constructor" property, which in turn references the function itself. This is a circular reference (i.e. animal.prototype.constructor===animal)

Console.log (' **************constructor**************** '); Console.log (' Anim.constructor===animal: ' + (anim.constructor===animal))    ;    Trueconsole.log (' Animal===animal.prototype.constructor: ' + (animal===animal.prototype.constructor))    ;    Trueconsole.log (' Animal.constructor===function.prototype.constructor: ' + (animal.constructor=== Function.prototype.constructor));   Trueconsole.log (' function.prototype.constructor===function: ' + (function.prototype.constructor===function));    Trueconsole.log (' Function.constructor===function.prototype.constructor: ' + (function.constructor=== Function.prototype.constructor));    Trueconsole.log (' Object.prototype.constructor===object: ' + (Object.prototype.constructor===object));    Trueconsole.log (' object.constructor====function: ' + (object.constructor===function));    True

The __proto__ used in the above code is currently not supported in IE6/7/8/9. You can use Object.getprototypeof (ES5) in IE9 to get an internal prototype of an object.

var p = {}var __proto__ = object.getprototypeof (P) console.log (__proto__ = = = Object.prototype)//True

Performance

Finding properties on the prototype chain is time consuming and has side effects on performance, which is important in demanding performance situations. In addition, attempting to access an attribute that does not exist traverses the entire prototype chain.

When iterating through the properties of an object, each property on the prototype chain is enumerable.

It is necessary to use the hasOwnProperty method, which is inherited from all objects, to detect whether the object's properties are defined on itself or on the prototype chain Object.proptotype .

hasOwnProperty is the only method in JavaScript that involves only the object's own properties and does not traverse the prototype chain.

Note: Just by judging whether a value is undefined is not enough to detect whether a property exists, a property may exist and its value is exactly undefined .

Bad practice: Extending prototypes of Native objects

A frequently used bad practice is the Object.prototype prototype of an extension or other built-in object.

This technique is called monkey patching, which destroys the encapsulation of objects. While some popular frameworks (such as prototype.js) are using the technology, the technology is still not a good practice, and the additional nonstandard approach makes the built-in type confusing.

The only justification for extending the built-in object prototype is to migrate the features of the newer JavaScript engine, such as Array.forEach .

Conclusion

It is important to understand the prototype inheritance model before writing complex code that uses the prototype inheritance model. Also, be aware of the length of the prototype chain in your code and, if necessary, end the prototype chain to avoid possible performance problems. Further, you should never extend the prototype of a native object unless you are compatible with the new JavaScript feature.

Reference articles

Http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

Http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript

http://segmentfault.com/q/1010000003791600?_ea=368532

Https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto

Https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain

Inheritance and prototype chains in JavaScript

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.