JavaScript object-oriented and prototype _javascript techniques

Source: Internet
Author: User
Tags shallow copy hasownproperty

ECMAScript has two development modes: 1. Functional (procedural); 2. object-oriented (OOP);

Create an Object
1. Common objects of Creation

Create an object, and then give the object new properties and methods;
  var box = new Object ();       Creates an object;
  Box.name = ' Lee ';          Create a Name property and assign a value;
  Box.age = m;
  Box.run = function () {        //Create a run () method and return a value;
    Return this.name+this.age+ ' running ... ';
  } 
  Console.log (Box.run ());       Enter values for properties and methods;
Disadvantage: If you want to create a similar object, you will generate a lot of code;

2. Factory Pattern Creation Object

This method is to solve the problem that the instantiation object produces a lot of code duplication;
  function CreateObject (name,age) {    //set to create the body of functions;
    var obj = new Object; function body to create object;
    Obj.name = name; 
    Obj.age = age;
    Obj.run = function () {return
      this.name+this.age+ "Run ...";
    };
    return obj;
  }
  var box1 = CreateObject ("Lee");   instantiation; Calling functions and passing parameters;
  var Box2 = CreateObject ("Jack");  Example two;
  Console.log (Box1.run () +box2.run ());   Examples remain relatively independent;
Disadvantages: The identification of objects and instances; it's impossible to figure out exactly what they are as examples of that object;
  Console.log (typeof box1);        Object;

3. Constructor Creation Object

ECMAScript use Constructors (construction methods) to create specific objects;
  function Box (name,age) {//constructor mode;
    THIS.name = name; This represents object box;
    This.age = age;
    This.run = function () {return
      this.name+this.age+ "Running ...";}
  var box1 = new Box ("Lee");     An instance of an object must be created with the new operator;
  var box2 = new Box ("Jack");    Box1 and Box2 are examples of box objects;
  Console.log (box1 instanceof Box);   true; a clear identification of box1 from the box;
Using constructors, the problem of repeated instantiation is solved, and the problem of object recognition is solved.

using constructors differs from Factory mode:
(1). The Creation object (new object) that is not displayed by the constructor method;
(2). Assign properties and methods directly to the This object;
(3). No return statement; 1//Constructor specification:
(1). The Function name (functions box) and the instantiated Construction name (new box) are the same and uppercase;
(2). To create an instance object from a constructor, you must use the new operator;

The difference between a constructor and a normal function:
  var box = new Box (' Lee ');        construct pattern invocation;
  Box (' Lee ');               Normal mode call, invalid;

  var o = new Object ();
  Box.call (O, ' Jack ', MB);           Object impersonating the call;
  Expands the Box object scope to object o; The box () method's operating environment has become an object o;

problem with constructors:
when you use constructors to create each instance, the methods in the constructor are recreated on each instance;
Because the functions in the ECMAScript are objects, each definition of a function is an instance of an object;
Creating functions in this way results in different scope chains and identifiers parsing;

Two prototypes
//Each function we create has a prototype (prototype) attribute, which is an object;

Purpose: Contains properties and methods that can be shared by all instances of a particular type;

Understanding: Prototype is the prototype object of the object created by invoking the constructor;

The advantage of using prototypes is that all object instances can share the properties and methods it contains;

That is, you do not have to define object information (Properties/methods) in the constructor, but you can add that information directly to the prototype;

1. Prototype mode (prototype add properties and methods)

1. Prototype mode function Box () {}//declaration constructor;           Box.prototype.name = ' Lee ';
  Adding attributes and methods to the prototype;
  Box.prototype.age = 100;
  Box.prototype.run = function () {return this.name+this.age+ ' run ... ';
  };
  var box1 = new Box ();
  var box2 = new Box ();        Console.log (Box1.run==box2.run);
The address of the =>true; method reference is consistent;
There are two more attributes in the prototype, both of which are generated automatically when the object is created;
 1.__PROTO__: A pointer to a prototype object; Its function: a property constructor to a stereotype of a constructor; 14//IE browser will not be recognized in script access __proto__;
  15//To judge whether an instance object points to the prototype object of the constructor, you can use the isPrototypeOf () method to test it;  Console.log (Box.prototype.isPrototypeOf (Box)); =>true;

As long as the object is instantiated, that will point to;
The execution process of the prototype pattern://1. First find the property or method in the instance of the constructor object, and if so, return immediately;

2. If there are no instances of the constructor object, go to its prototype object and find it, if any, return it;
  Although we can access the values stored in the prototype through an object instance, we cannot access the values in the prototype by overriding the object instance;
  var box1 = new Box ();              Console.log (Box1.name); Lee;
  The value in the prototype;
  Bo1.name = ' Jack ';              Console.log (Box1.name);
  Jack; The value assigned by the instance itself;
  var box2 = new Box ();              Console.log (Box2.name);
  Lee; The value in the prototype; not modified by box1; If you want Box1 to continue accessing the values in the prototype, you can constructThe deletion of the attribute in the creation function;                 Delete Box1.name;
  Deletes the instance's own properties;              Console.log (Box1.name); Lee; The original value in the prototype;

2. Prototypes and in Operators

How do you determine whether a property is in a constructor instance or in a prototype? The hasOwnProperty () function can be used to verify;
Console.log (Box.hasownproperty (' name ')); Returns False if there is a return true in the instance;
The In operator returns True when the given property is accessible through the object, whether the property exists in the instance or in the prototype;
Console.log (' name ' in box); =>true, existing in an instance or in a prototype; 3. Simpler prototype syntax (prototype + literal mode)

3. Simpler prototype syntax (prototype + literal mode)

  function Box () {};
  Box.prototype = {                 //creates a literal form of the new object containing the properties and methods;
    Name: ' Lee ',
    age:100,
    run:function () {return
      this.name+this.age+ ' running ... '
    }
  };

Creating a prototype object using a constructor and using a literal to create a prototype object is basically the same in use;
However, a prototype object created with a literal is not pointing to an instance, but to a prototype object, or a constructor, using the constructor property instead;
  var box = new box ();
  Console.log (box instanceof box);
  Console.log (Box instanceof Object);  
  Console.log (box.constructor = = box);      Literal way, return false;
  Console.log (Box.constructor = = Object);     Literal method, returns true;
  If you want the literal way of constructor to point to the instance object:
  Box.prototype = {
    Constructor:box,              //Direct force point;
  }

  PS: Literal method Why does constructor point to object?
  Because box.prototype={} This literal writing is to create a new object;
  And every time you create a function, it creates its prototype, and the object automatically gets the constructor attribute;
  So, the constructor of the new object rewrites the original constructor of the box, so it points to the new object,
  ///The new object does not specify a constructor, then it is implicitly considered object;

4. The dynamics of the prototype (overrides will overwrite the previous content)

The declaration of the prototype is sequential, so the rewritten prototype will cut off the previous prototype;
  function Box () {};
  Box.prototype = {
    Constructor:box,
    name: ' Lee ',
    age:100,
    run:function () {return
      this.age+ ' run ...';
    }
  };
  Box.prototype = {                //prototype rewritten, overwriting previous prototypes;
    age:200,
    run:function () {return
      this.age+ ' run ... '
    }
  }
  var box = new box ();
  Console.log (Box.run ());              =>200 running ...;
  Rewriting a prototype object cuts off the connection between an existing prototype and any previously existing object instance, and the object instance references the original prototype;

5. Prototypes of native objects

A prototype object can be used not only in the context of custom objects, but also in ECMAScript built-in reference types.
and the built-in reference type itself is used as a prototype;
Console.log (Array.prototype.sort); =>function sort () {[native code]};
Console.log (String.prototype.substring); =>function substring () {[native code]};

6. Problems with prototype objects

Prototype schema creation Object disadvantage: The process of initialization of constructor parameters is omitted, and the disadvantage is that initialization values are consistent;
And the biggest of the prototype is sharing, attribute sharing;
However, if the attributes in the stereotype contain reference types (objects), there is a problem with sharing;
  function Box () {};
  Box.prototype = {
    Constructor:box,
    name: ' Lee ',
    age:100,
    family:[' father ', ' mother '],
    run: function () {return
      this.name+this.age+this.family;
    }
  };
  var box1 = new Box ();
  Box1.family.push (' sister ');           Added sister for the Box1 family attribute, which is shared to the prototype;
  Console.log (Box1.run ());            =>lee100father,mother,sister;
  var box2 = new Box ();
  Console.log (Box2.run ());            =>lee100father,mother,sister;
  Data sharing causes the instantiated data to not preserve its own characteristics;

7. Combined use of constructor patterns (data not shared by objects) and prototype mode (data shared by objects)

In order to solve the problem of constructive parameters and sharing, combinatorial constructor + Prototype mode: function
  Box (name,age) {             //unshared usage constructor;
    this.name = name;
    This.age = age;
    this.family = [' father ', ' moter '];
  Box.prototype = {                //Shared usage prototype mode;
    Constructor:box,
    run:function () {return
      this.name+this.age+this.family;
    }
  };
  PS: This hybrid mode is a good solution to the big problem of reference and sharing, it is a good way to create objects;

8. Dynamic prototyping mode (encapsulating prototypes into constructors)

The prototype pattern, whether or not it invokes a shared method in the prototype, initializes the method in the prototype;
And when declaring an object, the constructor + prototype makes people feel weird; it's best to encapsulate constructors and prototypes together;
  function Box (name,age) {              //encapsulates all information into the constructor body;
    this.name = name;
    This.age = age; 
    When the constructor is called for the first time, the run () method does not exist, and the initialization prototype is executed;
    When the second call is not initialized, and the new object is created for the second time, the prototype is not loaded with initialization;
    In this way, both the encapsulation and the prototype method are shared, and the attributes are independent.
    if (typeof this.run!= ' function ') {      //is initialized only on first invocation;
      Box.prototype.run = function () {return
        this.name+this.age+ ' run ... ';;}}
  ;
  var box = new Box (' Lee ');
  Console.log (Box.run ());
PS: Using dynamic prototyping mode, be aware that you can no longer use the literal way to rewrite the prototype, because it will cut off the relationship between the instance and the new prototype;

9. Parasitic constructors

Parasitic constructors, in fact, are Factory mode + construction mode; This model is more general, but it can't determine object relation;
  function Box (name,age) {
    var obj = new Object ();
    Obj.name = name;
    Obj.age = age;
    Obj.run = function () {return
      this.name+this.age+ ' run ... ';
    };
    return obj;
  }

Three inheritance
1. Prototype chain

Inheritance is a relatively core concept
in object oriented. Other Orthodox object-oriented languages implement inheritance in two ways: one is interface implementation, the other is inheritance;
The ECMAScript only supports inheritance, does not support interface implementation, and the way to implement inheritance relies on the prototype chain to complete;
Essence: Using a prototype to make a reference type inherit the properties and methods of another reference type;
  Prototype inheritance chain: Box ==>> Desk ==>> Table;
  function box () {                 //box construction;
    this.name = ' Lee ';
  }
  function Desk () {                //Desk construction;
    This.age = +;
  }
  Desk.prototype = new Box ();           By creating a box instance and assigning it to Desk.prototype, the chain  
                          is formed by a prototype; The essence is: Rewrite the prototype object of desk, and replace it with a new type of box case;
                          That is to say, the properties and methods that existed in the box instance are now in
  the Desk.prototype. var desk = new Desk ();
  Console.log (desk.age);             ;
  Console.log (desk.name);             =>lee;

  function Table () {
    this.level = ' AAA ';
  }
  Table.prototype = new Desk ();          Continuation of prototype chain inheritance; Table inherits the desk;
  var table = new Table ();
  Console.log (table.name);            Lee;

2. The relationship between prototype and instance;

PS: The above prototype chain inheritance is missing One ring, that is object, all constructors inherit from object;
The inherited object is automatically completed and does not require manual inheritance;
  Console.log (table instanceof Object);       =>true;
  Console.log (desk instanceof Table);        =>false;desk is a super class of table;
  Console.log (table instanceof Desk);        =>true;
  Console.log (table instanceof Box);         =>true;
In JS, the inherited function is called the supertype (the parent class, the base class);
Inherited functions are called subtypes (subclasses, derived classes);
Inheritance problem:
//literal rewrite prototype interrupts relationship;
The subtype cannot pass arguments to the superclass;

3. Borrow constructor (object impersonate)
To solve the problem of reference sharing and the inability to pass parameters to the super type;

Calls the superclass constructor inside the subtype constructor;
  function Box (age) {
    this.name = [' Lee ', ' Jack ', ' Hello '];
    This.age = age;
  }
  The function Desk (age) {
    //inherited box and passed parameters;
    As a result, all object initialization code defined in the box () function is executed on the new desk object;
    Box.call (this,age);              The object is impersonating, desk inherits box, and can pass the parameter to the super type;
    To ensure that the box constructor does not override the properties of a subtype, you can add a property
    that should be defined in the subtype after the superclass constructor. This.height = 175;

  }
  var desk = new Desk (200); to the desk () function, and then through the function to the box () function to pass the parameter;
  Console.log (desk.age);               =>200;
  Console.log (desk.name);              =>[' Lee ', ' Jack ', ' Hello ';
  Desk.name.push (' AAA ');               => added new data, only add to desk;
  Console.log (desk.name);              =>[' Lee ', ' Jack ', ' Hello ', ' AAA ';

4. Combinatorial Inheritance (prototype chain + borrow constructor)
Although the use of constructors solves the problem of reference sharing and the inability to pass the parameters to the superclass, it is not possible to reuse the prototype, so it is necessary to combine the inheritance mode;

Using the prototype chain to implement the inheritance of the prototype properties and methods;
The inheritance of the instance attribute is realized by borrowing the constructor function;
In this way, the function reuse is realized by defining the method on the prototype, and each instance has its own attribute.
  function Box (age) {  //constructor;
    THIS.name = [' Lee ', ' Jack ', ' Hello '];
    This.age = age;
  }
  Box.prototype.run = function () {//prototype;
    return this.name+this.age;
  }
  function Desk (age) {
    box.call (this,age);              Inheritance property; Object posing;                             By extending the scope of the box object to desk, desk inherits the properties and methods in box; 
  Desk.prototype = new Box ();            Inheritance method; Prototype chain inheritance;
  var desk = new desk (m);
  Console.log (Desk.run ());              =>lee,jack,hello100
//most commonly used inheritance model;

5. Prototype inheritance?

This inheritance uses prototypes and creates objects based on existing objects without having to create a custom type;
  function obj (o) {                //pass a literal functions;
    function F () {};               Create a constructor;
    F.prototype = O;              The literal function is assigned to the prototype of the constructor;
    return new F ();               Returns the instantiated constructor;
  var box = {                   //literal object;
    Name: ' Lee ',
    arr:[' brother ', ' Sisiter ']
  };
  var box1 = obj (box);
  Console.log (box1.name);             =>lee;
  Box1.name = ' Jack ';
  Console.log (box1.name);             =>jack;

  Console.log (Box1.arr);             =>brother,sister;
  Box1.arr.push (' father '); 
  Console.log (Box1.arr);             =>brother,sister,father;

  var box2 = obj (box);
  Console.log (box2.name);             =>lee;
  Console.log (Box2.arr);             =>brother,sister,father; reference types are shared;

6. Parasitic inheritance?

The prototype + factory model is combined to encapsulate the process of creating objects;
Create a function that encapsulates only the inheritance process, the function create
  (o) {               //encapsulation creation process;
    var f = obj (o);
    F.run = function () {return
      This.arr;            The same will share the reference;
    return f;
  }

7. Parasitic Modular inheritance?

Previously said, modular inheritance is JS most commonly used in the inheritance model;
  However, there are also problems with modular inheritance://The superclass is invoked two times during use: one time when the subtype is created, and the other is within the subtype constructor;
    function Box (name) {this.name = name;
  This.arr = [' brother ', ' sister '];
  } Box.prototype.run = function () {return this.name;            function Desk (name,age) {box.call (this,name);
    The second time box is called;
  This.age = age;           } Desk.prototype = new Box ();

Call box for the first time;
Parasitic modular Inheritance://Through the use of constructors to inherit attributes,//through the prototype chain of the hybrid form to inherit the method;
  Solved the problem of two calls;
    function obj (o) {function F () {};
    F.prototype = O;
  return new F ();
    function Create (Box,desk) {var f = obj (Box.prototype);
    F.constructor = desk;
  Desk.prototype = f;
    function Box (name) {this.name = name;
  This.arr = [' brother ', ' sister '];
  } Box.prototype.run = function () {return this.name;
    function Desk (name,age) {box.call (this,name);
  This.age = age;            } inheritprototype (Box,desk);

  To achieve inheritance through here;
  var desk = new Desk (' Lee ', 100);
  Desk.arr.push (' father '); ConsolE.log (Desk.arr);

  Console.log (Desk.run ());
  var desk2 = new Desk (' Jack ', 200);              Console.log (Desk2.arr); Two times of reference problem solving;

Iv. Summary


1. Creating objects

objects can be created and enhanced during code execution, and therefore have dynamic rather than strictly defined entities;
In the absence of classes, you can create objects in the following patterns;
(1). Factory mode: Create objects with simple functions, add properties and methods to objects, and return objects;
This pattern was later replaced by the constructor pattern;
(2). Constructor pattern: You can customize a reference type to use the new operator as you would a built-in object instance;
Disadvantage: None of its members can be reused, including functions; Because functions are not limited to any object, there is no reason not to share functions among multiple objects;
(3). Prototype mode: Use the prototype property of the function to specify the properties and methods that should be shared;
Use constructors to define instance properties and use prototypes to define shared properties and methods when combining constructor and prototype patterns;

2. Prototype chain

The construction of the prototype chain is realized by assigning an instance of a type to a prototype of another constructor;
Subtypes can access all properties and methods of a superclass;
The problem of the prototype chain is that object instances share all inherited properties and methods, so they are not suitable for individual use.
Solution: Borrow The constructor, that is, call the superclass constructor inside the subtype constructor;
This makes it possible for each instance to have its own attributes, while also ensuring that only constructors are used to define types;
The most used inheritance mode is combinatorial inheritance, which inherits the shared properties and methods using the prototype chain, and inherits the instance property by borrowing the constructor;

3. Inheritance model

(1). Prototype inheritance: It is possible to implement inheritance without having to define a constructor beforehand; its essence is to perform a shallow copy of a given object; A copy of the copied copy can be further modified by the
;
(2). Parasitic inheritance: Create an object based on an object or some information, then enhance the object, and finally return the object;
This pattern can be used in conjunction with composite inheritance in order to solve the inefficiency caused by the multiple invocation of a superclass constructor by a composite inheritance pattern;
(3). Parasitic modular inheritance: a bit of parasitic inheritance and modular inheritance, which is the most efficient way to implement type-based inheritance;

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.