Summary of inheritance features in JavaScript programs, javascript features

Source: Internet
Author: User
Tags c constructor hasownproperty

Summary of inheritance features in JavaScript programs, javascript features

Overview
All JavaScript objects have their own inheritance chains. That is to say, each object inherits another object, which is called a prototype object. Except null, it does not have its own prototype object.

The importance of A prototype object is that if object A is A prototype of object B, object B can obtain all attributes and methods of object. The Object. getPrototypof method is used to obtain the prototype Object of the current Object.

var p = Object.getPrototypeOf(obj);

In the code above, object p is the prototype object of object obj.

The Object. create method is used to generate a new Object that inherits the specified Object.

var obj = Object.create(p);

In the above Code, the prototype of the newly generated obj object is object p.

The non-standard _ proto _ attribute (two underscores (_) before and after each) can rewrite the prototype object of an object. However, you should try to use this attribute as little as possible, but use Object. getPrototypeof () and Object. setPrototypeOf () to read and write the prototype Object.

var obj = {};var p = {};obj.__proto__ = p;Object.getPrototypeOf(obj) === p // true

The code above uses the _ proto _ attribute to set the p object as the prototype of the obj object.

The following is an actual example.

var a = {x: 1};var b = {__proto__: a};b.x // 1

In the code above, object B sets its prototype object as object a through the _ proto _ attribute. Therefore, object B can obtain all attributes and methods of object. Object B does not have the x attribute, but the JavaScript engine uses the _ proto _ attribute to find its prototype object a and then reads the x attribute of object.

The new command creates an instance object through the constructor. In essence, it binds the prototype attribute of the constructor to the prototype attribute of the Instance Object and then executes the constructor on the instance object.

Var o = new Foo (); // equivalent to var o = new Object (); o. _ proto _ = Foo. prototype; Foo. call (o );

The _ proto _ attribute of the prototype object can also point to other objects to form a prototype chain at the first level ).

var a = { x: 1 };var b = { __proto__: a };var c = { __proto__: b };c.x // 1

It should be noted that, at the first level, finding an attribute in the prototype chain has an impact on performance. The prototype object with the search attributes on the upper layer has a greater impact on performance. If an attribute does not exist, the entire prototype chain is traversed.

This action points
No matter where this is defined, it always points to the current object instead of the prototype object.

var o = { a: 2, m: function(b) {  return this.a + 1; }};var p = Object.create(o);p.a = 12;p.m() // 13

In the above Code, the m method of the p object comes from its prototype object o. In this case, the this object inside the m method does not point to o, but to p.

Constructor inheritance
This section describes how to let a constructor inherit from another constructor.

Assume there is a Shape constructor.

Function Shape () {this. x = 0; this. y = 0;} Shape. prototype. move = function (x, y) {this. x + = x; this. y + = y; lele.info ('shape moved. ') ;}; Rectangle constructor inherits Shape. Function Rectangle () {Shape. call (this); // call the parent class constructor} // function Rectangle () {this. base = Shape; this. base ();} // subclass inherits the Rectangle of the parent class. prototype = Object. create (Shape. prototype); Rectangle. prototype. constructor = Rectangle; var rect = new Rectangle (); rect instanceof Rectangle // truerect instanceof Shape // truerect. move (1, 1) // 'shape moved.'

The code above indicates that the inheritance of constructor is divided into two parts: one is that the subclass calls the constructor of the parent class, and the other is that the prototype of the subclass points to the prototype of the parent class.

In the code above, the subclass inherits the parent class as a whole. Sometimes, only the inheritance of a single method is required. The following code can be used.

ClassB.prototype.print = function() { ClassA.prototype.print.call(this); // some code}

In the above Code, the print method of subclass B first calls the print method of parent class A, and then deploys its own code. This inherits the print method of the parent Class.

_ Proto _ attributes
The _ proto _ property points to the prototype object of the current object, that is, the prototype attribute of the constructor.

var obj = new Object();obj.__proto__ === Object.prototype// trueobj.__proto__ === obj.constructor.prototype// true

The code above first creates an Object obj whose _ proto _ property points to the prototype attribute of the constructor (Object or obj. constructor. Therefore, true is returned after the two are compared.

Therefore, there are three methods to obtain the prototype object of the Instance Object obj.

  • Obj. _ proto __
  • Obj. constructor. prototype
  • Object. getPrototypeOf (obj)

Among the above three methods, the first two are not very reliable. The latest ES6 standard stipulates that, __proto _ attributes must be deployed only by the browser, and other environments may not be deployed. Obj. constructor. prototype may become invalid when you manually change the prototype.

var P = function () {};var p = new P();var C = function () {};C.prototype = p;var c = new C();c.constructor.prototype === p // false

In the code above, the prototype object of the C constructor is changed to p, and the result is that c. constructor. prototype is distorted. Therefore, when changing a prototype object, you must set the constructor attribute at the same time.

C.prototype = p;C.prototype.constructor = C;c.constructor.prototype === p // true

Therefore, we recommend that you use the third Object. getPrototypeOf method to obtain the prototype Object. The usage of this method is as follows.

var o = new Object();Object.getPrototypeOf(o) === Object.prototype// true

You can use the Object. getPrototypeOf method to check whether the browser supports the _ proto _ attribute. The old browser does not support this attribute.

Object.getPrototypeOf({ __proto__: null }) === null

The code above sets the _ proto _ attribute of an Object to null, and then obtains the prototype of the Object using the Object. getPrototypeOf method to determine whether it is equal to null. If the current environment supports the _ proto _ attribute, the comparison result of the two should be true.

With the _ proto _ attribute, you can easily set the prototype of the Instance Object. Assume that there are three objects: machine, vehicle, and car. machine is the prototype of vehicle, and vehicle is the prototype of car. You only need two lines of code.

vehicle.__proto__ = machine;car.__proto__ = vehicle;

The following is an example. You can use the _ proto _ attribute and constructor. prototype attribute methods to read the properties defined on the prototype object.

Array.prototype.p = 'abc';var a = new Array();a.__proto__.p // abca.constructor.prototype.p // abc

Apparently, __proto _ looks more concise.

When an instance object is generated through the constructor, the _ proto _ attribute of the Instance Object automatically points to the prototype object of the constructor.

var f = function (){};var a = {};f.prototype = a;var o = new f();o.__proto__ === a// true

Property inheritance
There are two types of attributes. One is the native attribute of the object itself, and the other is the inheritance attribute inherited from the prototype.

Native attributes of Objects
All attributes of an Object can be obtained using the Object. getOwnPropertyNames method.

Object.getOwnPropertyNames(Date)// ["parse", "arguments", "UTC", "caller", "name", "prototype", "now", "length"]

Some of the attributes of an object can be enumerable or not. Obtain only the enumerated attributes, and use the Object. keys method.

Object.keys(Date) // []hasOwnProperty()

The hasOwnProperty method returns a Boolean value to determine whether an attribute is defined on the object or the prototype chain.

Date.hasOwnProperty('length')// trueDate.hasOwnProperty('toString')// false

The hasOwnProperty method is the only method in JavaScript that does not traverse the prototype chain when processing object properties.

Object Inheritance attributes
Objects created using the Object. create method inherit the attributes of all prototype objects.

var proto = { p1: 123 };var o = Object.create(proto);o.p1 // 123o.hasOwnProperty("p1") // false

Get all attributes
Use the in operator to determine whether an object has a certain attribute (whether it is its own or inherited.

"length" in Date // true"toString" in Date // true

You can use the for-in loop to obtain all the enumerated attributes of an object (whether its own or its inherited attributes.

var o1 = {p1: 123};var o2 = Object.create(o1,{ p2: { value: "abc", enumerable: true }});for (p in o2) {console.info(p);}// p2// p1

To obtain the attributes of an object in the for... in loop, you can use the hasOwnProperty method to judge.

for ( var name in object ) { if ( object.hasOwnProperty(name) ) {  /* loop code */ }}

You can use the following function to obtain all attributes of an object (whether it is its own, its inheritance, or its enumeration.

function inheritedPropertyNames(obj) { var props = {}; while(obj) {  Object.getOwnPropertyNames(obj).forEach(function(p) {   props[p] = true;  });  obj = Object.getPrototypeOf(obj); } return Object.getOwnPropertyNames(props);}

The usage is as follows:

inheritedPropertyNames(Date)// ["caller", "constructor", "toString", "UTC", "call", "parse", "prototype", "__defineSetter__", "__lookupSetter__", "length", "arguments", "bind", "__lookupGetter__", "isPrototypeOf", "toLocaleString", "propertyIsEnumerable", "valueOf", "apply", "__defineGetter__", "name", "now", "hasOwnProperty"]

Object copy
To copy an object, you need to do the following two things.

Make sure that the Copied object has the same prototype as the original object.
Make sure that the Copied object has the same attributes as the original object.
The following is the object copy function based on the above two points.

function copyObject(orig) { var copy = Object.create(Object.getPrototypeOf(orig)); copyOwnPropertiesFrom(copy, orig); return copy;}function copyOwnPropertiesFrom(target, source) { Object .getOwnPropertyNames(source) .forEach(function(propKey) {  var desc = Object.getOwnPropertyDescriptor(source, propKey);  Object.defineProperty(target, propKey, desc); }); return target;}

Multi-Inheritance
JavaScript does not provide multiple inheritance functions, that is, it does not allow an object to inherit multiple objects at the same time. However, you can use a work und to implement this function.

function M1(prop) { this.hello = prop;}function M2(prop) { this.world = prop;}function S(p1, p2) { this.base1 = M1; this.base1(p1); this.base2 = M2; this.base2(p2);}S.prototype = new M1();var s = new S(111, 222);s.hello // 111s.world // 222

In the code above, subclass S inherits both the parent Class M1 and M2. Of course, from the perspective of the inheritance chain, S has only one parent Class M1, but because the constructor M1 and M2 are executed simultaneously on the S instance, therefore, it inherits the methods of these two classes at the same time.

Related Article

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.