Your location:Tech News>News>Script>15 minutes in-depth understanding of JS inherited classification, principles and usage

Latest News

15 minutes in-depth understanding of JS inherited classification, principles and usage

Author:fsadmin

Views:

  This article describes the overall classification JS inheritance, principles and usage.Share to you for your reference, as follows:

  Many OO languages supports two types of inheritance: implementation inheritance and interface inheritance.Interface inheritance inherit only the method signature, but the actual implementation inheritance inherited method.Since the function ECMAScript is not signed, it can not be implemented in the JS interface inheritance.ECMAScript only supports implementation inheritance, and its implementation inheritance relies mainly on the prototype chain to achieve.Therefore, I say below prototype inheritance chain, borrow constructor inheritance, composition inherited, inherited, the prototype, combined parasitic Parasitic inheritance and inheritance belong inheritance.

  Finally, the last, I will explain grammar in use ES6 are combined parasitic inheritance.

  1. Prototype inheritance chain

  ECMAScript described concept prototype chain, as a main chain and a method prototype implementation inheritance.The basic idea is to use the prototype to make a reference type inherits from another type of reference properties and methods.Prototyping inheritance chain has a basic mode, the code is as follows:

  function SuperType () {

  this.property = true;

  }

  SuperType.prototype.getSuperValue = function () {

  return this.property;

  };

  function SubType () {

  this.subproperty = false;

  }

  SubType.prototype = new SuperType (); // blackboard knock!This is the key: inherited SuperType

  SubType.prototype.getSubValue = function () {

  return this.subproperty;

  };

  var instance = new SubType ();

  alert (instance.getSuperValue ()); // true

  A prototype chain nature inherited prototype object is rewritten and replaced by a new instance of the type; prototype method for adding to the code must be placed after the replacement prototype statement; achieved when inherited through the prototype chain, can not use the object literal prototyping method.

  Examples of attributes instantiated, the object will be mounted in the example below, the so called instance attribute.The above code, after completion of the statement is executed, the original SuperType instance attribute property on the object mounted below.This is actually a risk, the specific reasons will be mentioned later.

  Every time I go to find a property or method when, in the case of a property or method can not be found, the search process is always to be ahead of a ring of the prototype chain will stop.

  All reference types are inherited by default Object, and this is achieved through the prototype inheritance chain.It can be seen, all the functions are default prototype object instances, the default function prototype will include an internal pointer to Object.prototype .

  Disadvantages:

  The main problem comes from the prototype contains a reference type value.When inheritance is implemented by the prototype, the prototype will actually become another example of the type of.Thus, the original instance properties will naturally become the prototype property now.

  In creating the instance subtype, can not pass parameters to the constructor supertype.

  * Off-topic: two ways to determine the relationship between the prototype and example

  The first way is to use instanceOf operator, as long as the prototype chain operator to test whether or not there have been instances of a constructor.If so, it returns true; if not, it will return false .Following is sample code:

  alert (instance instanceof Object); // true

  alert (instance instanceof SuperType); // true

  alert (instance instanceof SubType); // true

  The second way is to use isPrototypeOf () method.Similarly, as long as the emergence of the prototype chain had a prototype, it can be said to be the prototype of the prototype chain derived from the example of.Following is sample code:

  alert (Object.prototype.isPrototypeOf (instance)); // true

  alert (SuperType.prototype.isPrototypeOf (instance)); // true

  alert (SubType.prototype.isPrototypeOf (instance)); // true

  2. Borrowing constructor inheritance

  Borrowing constructor inheritance, also known as counterfeit objects or classical inheritance.The basic idea is quite simple, that is to call the constructor in the super-type internal sub-type constructor.Code of succession is as follows:

  function SuperType () {

  this.colors = [ "red", "blue", "green"];

  }

  function SubType () {

  SuperType.call (this); // knock blackboard!Note here inherited SuperType

  }

  var instance1 = new SubType ();

  instance1.colors.push ( "black");

  alert (instance1.colors); // "red, blue, green, black"

  var instance2 = new SubType ();

  alert (instance2.colors); // "red, blue, green"

  Call the parent class constructor under subclass instance environment by using a method (or methods may be), we are actually in the (future will) newly created.

  To ensure that the superclass constructor will not rewrite subtype attributes, after calling the super type constructor, add the attribute should be defined in the sub-types.

  Advantage: passing parameters to the constructor supertype subtype constructor.

  Disadvantages:

  The method is defined in the constructor, each instantiation, a method of the object is newly created, so the function simply can not multiplexed;

  Using this schema definition from the method defined types, supertypes prototype defined in terms of sub-type is not visible.

  3. A combination of inheritance

  Inheritance combination (combination inheritance), sometimes called pseudo-classical inheritance, the idea behind it is a prototype of the prototype implementation inheritance chain properties and methods, and to achieve an instance attribute inherited by borrowed constructor.Code of succession is as follows:

  function SuperType (name) {

  this.name = name;

  this.colors = [ "red", "blue", "green"];

  }

  SuperType.prototype.sayName = function () {

  alert (this.name);

  };

  function SubType (name, age) {

  SuperType.call (this, name); // inherit property

  this.age = age; // first inheritance, after the definition of new custom attributes

  }

  SubType.prototype = new SuperType (); // inherited methods

  Object.defineProperty (SubType.prototype, "constructor", {// first inheritance, after the definition of new custom attributes

  enumerable: false, // declare that the data can not enumerate the properties --constructor

  value: SubType

  });

  SubType.prototype.sayAge = function () {// first succession, the new custom method defined

  alert (this.age);

  };

  var instance1 = new SubType ( "Nicholas", 29);

  instance1.colors.push ( "black");

  alert (instance1.colors); // "red, blue, green, black"

  instance1.sayName (); // "Nicholas"

  instance1.sayAge (); // 29

  var instance2 = new SubType ( "Greg", 27);

  alert (instance2.colors); // "red, blue, green"

  instance2.sayName (); // "Greg";

  instance2.sayAge (); // 27

  advantage:

  It combines the prototype chain to inherit and borrow constructors inherited advantages, avoiding their defects;

  And it can also be used for object recognition based on a combination of inheritance created.

  Disadvantages:

  When implementing inheritance, no matter under what circumstances, will be called twice over type constructors: one is in the creation of sub-type prototype, and once inside the sub-type constructor.Subtype prototype will eventually contain all the instance properties of super-type object, but we have to override these attributes when defining a subtype constructor, because subtype prototype is best not to have a reference type value.But in practice, it causes a waste of memory.

  4. Prototypal inheritance

  Prototypal inheritance uphold the idea is: in the case of having to create a custom type, with the prototype chain, create new objects based on existing objects.Which method will be used, let''s take a look at the principles of the code of the method it:

  function object (o) {

  function F () {}

  F.prototype = o;

  return new F ();

  }

  In essence, the object of which is to perform a shallow copy incoming.

  ECMAScript 5 wanted to standardize the prototype formula inherited by methods.This method takes two parameters: a parameter is used as a new target object prototype; second parameter is an optional, additional definition object a new object property, the same format and parameters of two reference format.The following sample code is the prototype inheritance of formula:

  var person = {

  name: "Nicholas",

  friends: [ "Shelby", "Court", "Van"]

  };

  var anotherPerson = Object.create (person, {

  name: {

  value: "Greg"

  }

  });

  anotherPerson.friends.push ( "Rob");

  alert (anotherPerson.name); // "Greg"

  var yetAnotherPerson = Object.create (person);

  yetAnotherPerson.name = "Linda";

  yetAnotherPerson.friends.push ( "Barbie");

  alert (person.friends); // "Shelby, Court, Van, Rob, Barbie"

  Disadvantages: a reference type attribute values for all instances will always shared source object.

  5. Parasitic inheritance

  Parasitic (parasitic) inherited ideas and parasitic constructors and factory pattern is similar, only the creation of a succession process for encapsulating function, the function internally in some way to enhance the object, and finally it is really like to do Like all return to the work object.Let''s look at the sample code Parasitic inheritance:

  function object (o) {

  function F () {}

  F.prototype = o;

  return new F ();

  }

  function createAnother (original) {

  var clone = object (original); // create a new object by calling the function

  clone.sayHi = function () {// some way to enhance this object

  alert ( "hi");

  };

  return clone; // return the object

  }

  The inheritance pattern is actually the original inheritance into the function, and enhance the object inside, and then return it.Equivalent to prototype inheritance parasitic type in function, hence the name Parasitic inheritance.

  When using the foregoing exemplary inheritance pattern object () function is not required; any object capable of returning a new functions for this mode.

  Disadvantages: can not do with the function of the complex, inefficient.

  6. Combined parasitic inheritance (recommended)

  Combined parasitic inheritance, i.e., inherit attributes by borrowing the constructor, by the blend to form prototype chain inherited methods.The basic idea behind it is: do not have to specify the subtype of the type of prototype and call the super constructor, we need nothing more than a copy of the super-type prototype of it.In essence, it is the use of Parasitic inheritance to inherit the super-type prototype, and then assign the result to a subtype of the prototype.The following is a combined parasitic inherited code examples:

  function object (o) {

  function F () {}

  F.prototype = o;

  return new F ();

  }

  function inheritPrototype (subType, superType) {

  var prototype = object (superType.prototype); // create an object

  prototype.constructor = subType; // Enhanced Object

  subType.prototype = prototype; // specified object

  }

  function SuperType (name) {

  this.name = name;

  this.colors = [ "red", "blue", "green"];

  }

  SuperType.prototype.sayName = function () {

  alert (this.name);

  };

  function SubType (name, age) {

  SuperType.call (this, name); // inherit property

  this.age = age;

  }

  inheritPrototype (SubType, SuperType); // inherited prototyping

  SubType.prototype.sayAge = function () {

  alert (this.age);

  };

  advantage:

  Called only once super-type constructor;

  To avoid creating unnecessary in the sub-class prototype, the excess property, save memory space;

  But also the normal prototype chain remains unchanged, which means normal use instanceOf and isPrototypeOf () object-recognition.

  Inheritance parasitic combined is the best inheritance.

  7. extend the inheritance ES6

  Look at how to implement the sample code ES6 extend in succession: the contents of this one explanation, I was reading this article, learn the original text, please poke here ~

  class Child extends Parent {

  name = ''qinliang'';

  sex = "male";

  static hobby = "pingpong"; // static variable

  constructor (location) {

  super (location);

  }

  sayHello (name) {

  super.sayHello (name); // super call the parent class method

  }

  }

  We look at the code is compiled after the babel of _inherit () method:

  function _inherits (subClass, superClass) {

  // SuperClass must be a function, while the non-null

  if (typeof superClass !== "function" && superClass !== null) {

  throw new TypeError ( "Super expression must either be null or a function, not" + typeof superClass);

  }

  subClass.prototype = Object.create (// parasitic combined inheritance

  superClass && superClass.prototype, // methods, properties on the prototype were all inherited the

  {

  constructor: {// and defines a new attribute, here is the constructor property rewrite

  value: subClass,

  enumerable: false, // and realized the property can not enumerate

  writable: true,

  configurable: true

  }

  }

  );

  if (superClass) // implementation inheritance class static variables

  Object.setPrototypeOf ? Object.setPrototypeOf (subClass, superClass): subClass.__proto __ = superClass;

  }

  From here we can clearly see ES6 syntax, when the internal implementation inheritance, using a combination of parasitic inheritance.

  Let us look after compiling, in addition to other methods of compiling the results of the code:

  "Use strict";

  var _createClass = function () {// create a custom type using the prototype model

  function defineProperties (target, props) {// set of attributes characteristic data

  for (var i = 0; i < props.length; i++) {

  var descriptor = props [i];

  descriptor.enumerable = descriptor.enumerable || false;

  descriptor.configurable = true;

  if ( "value" in descriptor)

  descriptor.writable = true;

  Object.defineProperty (target, descriptor.key, descriptor);

  }

  }

  return function (Constructor, protoProps, staticProps) {

  // set the prototype to the prototype property of the Constructor

  if (protoProps) defineProperties (Constructor.prototype, protoProps);

  // set the static type of property Constructor

  if (staticProps) defineProperties (Constructor, staticProps);

  return Constructor;

  };

  } ();

  The method will first call the parent class before var _get = function get (object, property, receiver) {// call subclass of

  // default from Function.prototype of the acquisition method

  if (object === null) object = Function.prototype;

  // Get the specified parent class prototype chain

  var desc = Object.getOwnPropertyDescriptor (object, property);

  if (desc === undefined) {

  var parent = Object.getPrototypeOf (object); // continue up to get the parent class prototype

  if (parent === null) {

  return undefined;

  } Else {// continue receiving method specified parent class prototype

  return get (parent, property, receiver);

  }

  } Else if ( "value" in desc) {

  return desc.value; // the return value of the acquired

  } Else {

  var getter = desc.get; // get the prototype getter method

  if (getter === undefined) {

  return undefined;

  }

  return getter.call (receiver); // then calls the getter method, and pass in this subject

  }

  };

  function _classCallCheck (instance, Constructor) {// ensure our instance of an object is a specific type

  if (!(Instance instanceof Constructor)) {

  throw new TypeError ( "Can not call a class as a function");

  }

  }

  // call the constructor of the parent class constructor in subclass

  function _possibleConstructorReturn (self, call) {// this is a subclass parameter, two parameters parent class constructor

  if (!self) {

  throw new ReferenceError ( "this has not been initialised - super () has not been called");

  }

  return call && (typeof call === "object" || typeof call === "function") ? call: self;

  }

  var Child = function (_Parent) {

  _inherits (Child, _Parent);

  function Child (location) {// static variable

  _classCallCheck (this, Child); // this point detection problem

  // call the constructor of the parent class, and pass parameters when calling the subclass generate this parent class or subclass own this

  var _this = _possibleConstructorReturn (this, (Child.__proto__ || Object.getPrototypeOf (Child)).call (this, location));

  _this.name = ''qinliang'';

  _this.sex = "male";

  return _this;

  }

  _createClass (Child, [{// update prototype of type Child

  key: "sayHello",

  value: function sayHello (name) {

  // super call the parent class method calls the super subclass.sayHello when the incoming parameters passed to the parent class

  _get (Child.prototype.__proto__ || Object.getPrototypeOf (Child.prototype), "sayHello", this).call (this, name);

  }

  }]);

  return Child;

  } (Parent);

  Child.hobby = "pingpong";

  From my comment function can be seen, in fact, the only time in succession parasitic modular type constructor calls super, so the sub-type constructor to initialize instance environment.From this point, we can be more certain ES6 extend the use of parasitic combined inheritance.

  More on JavaScript content you can also view the site topic: "javascript object-oriented introductory tutorial", "JavaScript error and debugging skills summary", "JavaScript data structures and algorithms skills summary", "JavaScript traversal algorithm and skills summary" and " JavaScript math usage summary "

  In this paper, we hope that the JavaScript programming help.

  You may also be interested in the article: Introduction JavaScript examples in a variety of combinations to inherit JavaScript parasitic combined inheritance principle and usage analysis summary JavaScript instance common inheritance patterns thorough understanding of object-oriented inheritance js js inherited several usage summary (apply, call, prototype) JavaScript is how to achieve inheritance (six ways) use JS to achieve polymerization text animation JavaScript inheritance and aggregation Detailed examples

Recommend article

Relate article