Home  >  Article  >  Web Front-end  >  Detailed explanation of prototype chain and borrowed constructor usage examples of JavaScript inheritance

Detailed explanation of prototype chain and borrowed constructor usage examples of JavaScript inheritance

伊谢尔伦
伊谢尔伦Original
2017-07-25 15:59:101420browse

Prototype chain

The simplest way to implement inheritance in JavaScript is to use the prototype chain, just point the prototype of the subtype to the instance of the parent type, that is, "subtype .prototype = new parent type ();", the implementation method is as follows:


// 为父类型创建构造函数
function SuperType() {
  this.name = ['wuyuchang', 'Jack', 'Tim'];
  this.property = true;
}

// 为父类型添加方法
SuperType.prototype.getSuerperValue = function() {
  return this.property;
}

// 为子类型创建构造函数
function SubType() {
  this.test = ['h1', 'h2', 'h3', 'h4'];
  this.subproperty = false;
}

// 实现继承的关键步骤,子类型的原型指向父类型的实例
SubType.prototype = new SuperType();

// 在此处给子类型添加方法,一定要在实现继承之后,否则会在将指针指向父类型的实例,则方法为空
SubType.prototype.getSubValue = function() {
  return this.subproperty;
}


/* 以下为测试代码示例 */
var instance1 = new SubType();
instance1.name.push('wyc');
instance1.test.push('h5');
alert(instance1.getSuerperValue());    // true
alert(instance1.getSubValue());      // false
alert(instance1.name);          // wuyuchang,Jack,Tim,wyc
alert(instance1.test);          // h1,h2,h3,h4,h5


var instance2 = new SubType();
alert(instance2.name);          // wuyuchang,Jack,Tim,wyc
alert(instance2.test);          // h1,h2,h3,h4

You can see that the above code is a simple inheritance implemented through the prototype chain, but see There are still some problems in the test code example. I believe that children who have read my blog post "Basic explanation of object-oriented JS, factory mode, constructor mode, prototype mode, hybrid mode, dynamic prototype mode" must know that the first problem with prototype chain code is that the prototype of the subtype is Instances of the parent type, that is, the properties of the parent type contained in the prototype of the subtype, resulting in prototype properties of reference type values ​​being shared by all instances. The instance1.name.push('wyc'); of the above code can prove the existence of this problem. The second problem with the prototype chain is that when creating an instance of a subtype, parameters cannot be passed to the constructor of the supertype. Therefore, in actual development, we rarely use the prototype chain alone.

Borrowing constructors

In order to solve the two problems existing in the prototype chain, developers began to use a technique called borrowing constructors to solve the problems existing in the prototype chain. The problem. The implementation idea of ​​this technology is also quite simple. You only need to call the constructor of the parent type within the constructor of the subtype. Don’t forget, a function is nothing but an object that executes code in a specific environment, so constructors can be executed via the apply() or call() methods. The code is as follows:


// 为父类型创建构造函数
function SuperType(name) {
  this.name = name;
  this.color = ['pink', 'yellow'];
  this.property = true;

  this.testFun = function() {
    alert('http://tools.jb51.net/');
  }
}

// 为父类型添加方法
SuperType.prototype.getSuerperValue = function() {
  return this.property;
}

// 为子类型创建构造函数
function SubType(name) {
  SuperType.call(this, name);
  this.test = ['h1', 'h2', 'h3', 'h4'];
  this.subproperty = false;
}

// 在此处给子类型添加方法,一定要在实现继承之后,否则会在将指针指向父类型的实例,则方法为空
SubType.prototype.getSubValue = function() {
  return this.subproperty;
}


/* 以下为测试代码示例 */
var instance1 = new SubType(['wuyuchang', 'Jack', 'Nick']);
instance1.name.push('hello');
instance1.test.push('h5');
instance1.color.push('blue');
instance1.testFun();            // http://tools.jb51.net/
alert(instance1.name);            // wuyuchang,Jack,Nick,hello
// alert(instance1.getSuerperValue());    // error 报错
alert(instance1.test);            // h1,h2,h3,h4,h5    
alert(instance1.getSubValue());        // false    
alert(instance1.color);            // pink,yellow,blue

var instance2 = new SubType('wyc');
instance2.testFun();            // http://tools.jb51.net/
alert(instance2.name);            // wyc    
// alert(instance2.getSuerperValue());    // error 报错
alert(instance2.test);            // h1,h2,h3,h4
alert(instance2.getSubValue());        // false
alert(instance2.color);            // pink,yellow

You can see that the constructor of the subtype SubType in the above code is implemented by calling the parent type "SuperType.call(this, name);" With the inheritance of properties, you can also pass parameters to the parent type when creating an instance of the subtype, but a new problem arises again. You can see that I defined a method in the constructor of the parent type: testFun, and a method in the prototype of the parent type: getSuperValue. However, after instantiating the subtype, you still cannot call the method getSuperValue defined in the prototype of the parent type. You can only call the constructor method of the parent type: testFun. This is the same as using only the constructor pattern when creating objects, making the function non-reusable. Considering these problems, the technique of borrowing constructors is rarely used alone.

Combined inheritance (prototype chain + borrowed constructor)

As the name suggests, combined inheritance is a pattern that combines the advantages of the prototype chain and borrowed constructors. . The implementation is also very simple. Since it is a combination, it certainly combines the advantages of both parties, that is, the prototype chain inherits the method, and the constructor inherits the properties. The specific code implementation is as follows:


// 为父类型创建构造函数
function SuperType(name) {
  this.name = name;
  this.color = ['pink', 'yellow'];
  this.property = true;

  this.testFun = function() {
    alert('http://tools.jb51.net/');
  }
}

// 为父类型添加方法
SuperType.prototype.getSuerperValue = function() {
  return this.property;
}

// 为子类型创建构造函数
function SubType(name) {
  SuperType.call(this, name);
  this.test = ['h1', 'h2', 'h3', 'h4'];
  this.subproperty = false;
}

SubType.prototype = new SuperType();

// 在此处给子类型添加方法,一定要在实现继承之后,否则会在将指针指向父类型的实例,则方法为空
SubType.prototype.getSubValue = function() {
  return this.subproperty;
}


/* 以下为测试代码示例 */
var instance1 = new SubType(['wuyuchang', 'Jack', 'Nick']);
instance1.name.push('hello');
instance1.test.push('h5');
instance1.color.push('blue');
instance1.testFun();            // http://tools.jb51.net/
alert(instance1.name);            // wuyuchang,Jack,Nick,hello
alert(instance1.getSuerperValue());      // true
alert(instance1.test);            // h1,h2,h3,h4,h5    
alert(instance1.getSubValue());        // false    
alert(instance1.color);            // pink,yellow,blue

var instance2 = new SubType('wyc');
instance2.testFun();            // http://tools.jb51.net/
alert(instance2.name);            // wyc    
alert(instance2.getSuerperValue());      // true
alert(instance2.test);            // h1,h2,h3,h4
alert(instance2.getSubValue());        // false
alert(instance2.color);            // pink,yellow

The above code inherits the properties of the parent type through SuperType.call(this, name); and inherits through SubType.prototype = new SuperType(); Methods of the parent type. The above code conveniently solves the problems encountered by the prototype chain and borrowing constructors, and has become the most commonly used instance inheritance method in JavaScript.

The above is the detailed content of Detailed explanation of prototype chain and borrowed constructor usage examples of JavaScript inheritance. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn