Explanation of JavaScript inheritance mechanism and simple-inheritance source code Analysis _javascript Skills

Source: Internet
Author: User

The old question, most people also may not be able to understand systematically. JavaScript language is not good for inheritance, it requires engineers to implement a complete set of inheritance mechanism. Here we have a system that grasps the techniques of using JavaScript inheritance.

1. Direct use of the prototype chain

This is one of the simplest forms of rudeness and is basically not available for specific projects. A simple demo is as follows:

function supertype () {
  this.property = true;
}
SuperType.prototype.getSuperValue = function () {return
  this.property;
}
Function subtype () {
  this.subproperty = false;
}
Inherit
subtype.prototype = new Supertype ();
SubType.prototype.getSubValue = function () {return
  this.subproperty;
}
var instance = new Subtype ();

The problem with this approach is that the attributes in the prototype are shared by the instance being used, and the other instances are affected by changing an inherited property through an instance. , which is clearly not a conventional inheritance.

2. Using constructors

A constructor is essentially just a function, it can be invoked in any scope, and a parent constructor can be invoked in a child constructor to achieve simple inheritance.

function supertype () {
  this.colors = {"Red", "Blue", "Green"}
}
function subtype () {
  Supertype.call (this);  
}
var instance = new Subtype ();

This implementation avoids the problem of multiple instances sharing properties, but there are new problems, such as inability to share functions, and instance instanceof supertype to False.

3. Combined use of prototypes and constructors

function Supertype (name) {
  this.name = name;
  This.colors = {"Red", "Blue", "Green"}
}
SuperType.prototype.sayName = function () {
  //code
}
Function subtype (name,age) {
  supertype.call (this,name); 
  This.age = age;
}
Subtype.prototype = new Supertype ();
var instance = new Subtype ();

Combining prototypes and constructors is the most commonly used inheritance pattern in JavaScript. In this way, each instance has its own properties and can share the methods in the prototype. But the disadvantage of this approach is that, in any case, the superclass constructor is invoked two times. One time is when you create a subclass prototype, and the other one is inside the subclass constructor. How do you solve this problem?

4. Parasitic Modular inheritance

Subtype's prototype does not have to be a supertype instance, just a constructor prototype is a generic object of the Supertype prototype. The Douglas Crockford method is as follows:

function Obejct (o) {
  function F () {};
  F.prototype = O;
  return new F ();
}

In fact, this is also the realization of object.create in ES5. Then we can modify the 3rd scenario in this article:

function Inheritprototype (subtype,supertype) {
  var prototype = object (Supertype.prototype);
  Prototype.constructor = subtype;
  Subtype.prototype = prototype;
}
function Supertype (name) {
  this.name = name;
  This.colors = {"Red", "Blue", "Green"}
}
SuperType.prototype.sayName = function () {
  //code
}
Function subtype (name,age) {
  supertype.call (this,name); 
  This.age = age;
}
Inheritprototype (subtype,supertype);
var instance = new Subtype ();

In fact, parasitic modular inheritance is a very good inheritance implementation mechanism, enough to cope with day-to-day use. What if we ask a higher requirement: How do you call a parent class in a subclass?

Implementation of 5.simple-inheritance Library

Look at this difficult to understand the code, at first I was rejected, but deep after the discovery of Daniel is Daniel, subtle ideas everywhere. I have a detailed comment for each line of code. If you want to know the details, be sure to study it in detail and read each line. I think the most subtle realization of this is the need to rewrite the parent class method on demand, in which the parent class's method of the same name can be invoked by _super in the instance object, similar to the Java implementation.

(function () {//initializing is used to control the initialization of the class, very cleverly, please note the use of the trick below//fntest returns a regular ratio expression that detects whether a function contains _super, so that it can be rewritten as needed to improve efficiency. Of course the browser returns a generic regular expression var initializing = False,fntest =/xyz/.test (function () {xyz;}) if it is not supported?
  /\b_super\b/:/.*/; Class of the base class for all classes, this is generally the Window object this.
  Class = function () {};
    Adds a extend method to the base class that inherits Class.extend = function (prop) from the base class {///Saves the prototype Var _super of the current class = This.prototype;
    Creates an object of the current class, which is used to assign values to the prototype of the subclass, where it is very ingenious to use the parent class instance as the prototype of the subclass, and avoids the initialization of the parent class (through initializing control of the closure scope) initializing = true;   
    var prototype = new This ();
    initializing = false; Assign a value in the parameter prop to prototype, where prop typically include the object for the INIT function and other functions (var name in prop) {//corresponding to the name function, which requires special handling and can be used in child functions after processing This._sup  ER () invokes the constructor with the same name as the parent class, where the Fntest is ingenious: Only the subclass contains _super words to process from write to improve efficiency prototype[name] = typeof Prop[name] = "function" &&
       typeof _super[name] = = "function" && fntest.test (prop[name))? (function (NAME,FN) {return function () {//_super Here is our keyword, we need to temporarily store var tmp = This._super;
          Here you can invoke the constructor of the parent class by This._super this._super = _super[name];
          Call subclass function Fn.apply (this,arguments);
        Recovers _super, if TMP is empty, does not need to restore tmp && (this._super = tmp);
    }) (Name,prop[name]): Prop[name]; //When new object is actually invoked, the Init method on the class prototype is called, noting that the parameters passed by the new call must correspond to the function Class () {if (!initializing &&am) parameter one by one. P  
      This.init) {this.init.apply (this,arguments);
    Set the prototype Class.prototype = prototype to the subclass;
    Set constructor Class.prototype.constructor = class for subclasses;
    Set the Extend method of subclasses so that subclasses can also be inherited by extend method class.extend = Arguments.callee;
  return Class; }
})();

By using the Simple-inheritance library, we can implement inheritance in a very simple way, whether we find inheritance particularly strong-typed language.

var Human = class.extend ({
 init:function (age,name) {
  this.age = age;
  this.name = name;
 ,
 say:function () {
  console.log ("I am a Human");
 }
);
var man = human.extend ({
  init:function (age,name,height) {
    this._super (age,name);
    this.height = height;
  }, 
  say:function () {
    this._super ();
    Console.log ("I am a Man"); 
  }
)
; var man = new Man (, ' Bob ', ' 191 ');
Man.say ();

To explain the JavaScript inheritance mechanism and simple-inheritance source analysis, I hope this article to share can help everyone.

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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.