JS Object-Oriented programming detailed _JAVASCRIPT skills

Source: Internet
Author: User
Tags mixed

Preface
In the larger world of JavaScript, the discussion of Object-oriented objects is two points: 1. JavaScript is a prototype oriented object-oriented language 2. Simulate the object-oriented approach of a class language. As for why to simulate the object-oriented language, I personally think: In some cases, the prototype model can provide some convenience, but in the complex application, the prototype based object-oriented system in the abstraction and inheritance of the unsatisfactory. Since JavaScript is the only scripting language supported by major browsers, the master has to use a variety of methods to improve language convenience, and the result is that the code it writes becomes more and more like the object-oriented approach in the class language, thus masking the nature of the JavaScript prototype system.

Object-oriented language based on prototype
The prototype pattern, like a class pattern, is a programming generic, a programming methodology. In addition, the recently-developed functional programming is also a programming generic. JavaScript's father Brendan Eich, in designing JavaScript, had no intention of adding class concepts to it from the outset, but instead borrowed two other prototypes: Self and Smalltalk.

Since the same object-oriented language, you have to create the object method. In a class language, an object is created based on a template, first defining a class as an abstraction of the real world, and then instantiating the object by a class, whereas in the prototype language the object is created in the form of a clone of another object, called the prototype object by the cloned parent.

The key to cloning is whether the language itself provides native cloning methods. In ECMAScript5, object.create can be used to clone objects.

var person = {
  Name: "Tree",
  age:25,
  say:function () {
    console.log ("I ' m tree."
  }
};

var clonetree = object.create (person);
Console.log (Clonetree);


The aim of the prototype model is not to get an identical object, but to provide an easy way to create objects (from JavaScript design patterns and development practices). But because of the language design problem, the JavaScript prototype has a lot of contradictions, and some of its complex syntax seems to be based on the class language, these grammatical problems conceal its prototype mechanism (from "The JavaScript language pristine"). Such as:

function person (name, age) {
  this.name = name;
  This.age = age;      
}

var p = new Person (' tree ', 25)

In fact, when a function object is created, the function constructor that produces it runs some code like this:

This.prototype = {Constructor:this}

The new function object is given a prototype property whose value is an object that contains the constructor property and the property value is the new function. When the new operator is used on a function, the value of the prototype property of the function is cloned as a prototype object. If the new operator is a method, its execution process is as follows:

Function.prorotype.new = function () {
  //) clones a new object with prototype property value as a prototype object
  var that = Object.create (this.prorotype );
  
  Change the This key in the function to point to this newly cloned object
  var other = this.apply (that, arguments);
  
  If the return value is not an object, returns the new Clone object return
  (Others && typeof other = = ' object ')? Other:that;
}

As you can see from the above, although calling a function with the new operator looks like creating an object using a template instantiation, it essentially clones the new object with a prototype object.

Because the newly cloned object can access all the methods and attributes of the prototype object, plus the characteristics of the new operator, this becomes the cornerstone of the prototype simulation of the class language.  

Using prototyping to simulate a class-type language
Abstraction

The prototype model is used to simulate the class, first is the abstract way. According to the characteristics of the JavaScript language, a class (actually a pseudo class) usually places a field in the constructor (actually the function called by the new operator, JavaScript itself does not have a constructor concept), and the method is placed in the prototype property of the function.

function person (name, age) {
  this.name = name;
  This.age = age;

Person.prototype.say = function () {
  console.log ("Hello, I ' m" + this.name);

Inherited

Inheritance is one of the most talked-about concepts in oo language. Many OO languages support two ways of inheriting: interface inheritance and implementation inheritance. Interface inherits the inherited method signature, while implementing inheritance inherits the actual method. However, it is not possible to implement interface inheritance in ECMAScript, only support implementation inheritance, and its implementation inheritance is mainly based on the prototype chain. (from "JavaScript Advanced Program Design" 6.3-inheritance) in the senior three, the author explores all kinds of simulation about inheritance, such as: Combinatorial inheritance, prototype inheritance, parasitic inheritance, parasitic combination inheritance, the ultimate parasitic modular is the basis of all simulated class-type inheritance.

function person (name, age) {
  this.name = name;
  This.age = age;

Person.prototype.say = function () {
  console.log ("Hello, I ' m" + this.name);

function Employee (name, age, Major) {
  person.apply (this, arguments);
  This.major = major;
};

Employee.prototype = Object.create (person.prototype);
Employee.prorotype.constructor = Employee;

Employee.prorotype.sayMajor = function () {
  console.log (this.major);
}

In the senior three, only a single inheritance solution, the simulation of multiple inheritance we have to find a way to ourselves. Because many inheritance has its own difficulty: if the object-oriented language supports many inheritance, it will encounter the famous diamond problem (Diamond Problem). Suppose there is an inheritance relationship like the one shown on the left, and there is a method foo in O, which is overridden by Class A and B, but is not overridden by the C class. So does C call Foo in a, or call Foo in B, when it calls?

Therefore, most languages do not support multiple inheritance, such as the Java Support single inheritance + interface form. JavaScript does not support interfaces, what to do if you want to simulate an interface in a language that does not support interfaces? The answer is the famous duck-type syndrome. Put in the actual code is mixed (mixin). The principle is simple:

 function Mixin (t, s) {for
    (Var p in s) {
      t[p] = s[p];
    }
  

It is worth mentioning that dojo solves multiple inheritance problems by leveraging MRO (method resolution order), that is, finding the search order in the class where the invoked method is located.

In this, we have already understood the basic principle of simulating the language of class. As a love-tossing programmer, I want to have my own way of simplifying the creation of classes:

    • Provides a convenient way to create a class without exposing the prototype property of the function
    • When overriding a parent class method in a subclass, you can provide a super function like Java to directly access the parent class's method of the same name
    • Add static variables and methods in a more convenient way without caring for prototype
    • Support attribute like C #

Finally, in drawing on the knowledge of Daniel's summary, I wrote my own class creation tool O.js:

(function (global) {var define = Global.define;
    if (define && DEFINE.AMD) {define ([], function () {return O;
  }); else {Global.
  o = o;

  function O () {};
    O.derive = function (sub) {debugger;
    var parent = this; Sub = sub?

    Sub: {};
    var o = Create (parent); var ctor = Sub.constructor | |
    function () {};//How to invoke the constructor of the parent class? var statics = Sub.statics | |
    {}; var ms = Sub.mixins | |
    []; var attrs = Sub.attributes | |

    {};
    Delete Sub.constructor;
    Delete Sub.mixins;
    Delete Sub.statics;

    Delete sub.attributes;
    Process inheritance Relationship ctor.prototype = O;
    Ctor.prototype.constructor = ctor;
    Ctor.superclass = parent;
    The Attributes//for (Var p in attrs) {object.defineproperties (Ctor.prototype, attrs) is processed by defineproperties method;
    }//Static properties Mixin (ctor, statics);
    Mixed with other properties and methods, note that the properties here are Mixin (Ctor.prototype, sub) That all instance objects can access and modify; Simulates multiple inheritance for mixin (var i = 0, len = ms.length; i < len; i++) {mixin (Ctor.prototype, ms[i] | |
    {});
    } ctor.derive = parent.derive;
      _super Functions ctor.prototype._super = function (f) {debugger;
    Return parent.prototype[f].apply (this, Array.prototype.slice.call (arguments, 1));
  return ctor;
    function Create (clazz) {var F = function () {};
    F.prototype = Clazz.prototype; F.prototype.constructor = F;
  You do not need to return the new F ();

  };
    function Mixin (t, s) {for (Var p in s) {t[p] = s[p];
 }}) (window);

Class is created in the following ways:

var person = o.derive ({
  constructor:function (name) {//constructor
    This.setinfo (name);
  },
  statics: {//static variable
    declaredclass: "Person"
  },
  attributes: {//Impersonation property Name in C #
    : {
      set:function (n) {
        this.name = n ;
        Console.log (this.name);
      },
      get:function () {return
        this.name + "Attribute";
      }
  }},
  share: "Asdsaf",//The variable is on the prototype object, shared
  setinfo:function (name) {//method
    this.name = name;
  }
) for all objects;
var p = new Person (' lzz ');
Console.log (p.name);//lzzattribute
Console.log (person);

Inherited:

var Employee = person.derive ({//subclass has parent class derived
  constructor:function (name, age) {
    this.setinfo (name, age);
  },
  statics: {
    declaredclass: "Employee"
  },
  setinfo:function (name, age) {
    this._super (' SetInfo '), //Call the parent class with the same name method
    this.age = age;
  }
);

var e = new Employee (' lll ');
Console.log (e.name);//lllattribute
Console.log (Employee);

The above is the entire content of this article, I hope to help you learn.

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.