JavaScript inheritance mechanism

Source: Internet
Author: User
Tags constructor extend inheritance shallow copy jquery library

To clarify the first, Java and JavaScript is the relationship between Lei Feng and Leifeng Pagoda. JavaScript formerly known as Mocha, was also called LiveScript, the creator is Brendan Eich, is currently the chief technology officer of Mozilla company.

1994, the first relatively mature web browser--navigator0.9 version was born in Netscape (Netscape), a sensational.

However, Navigator0.9 can only be used to browse, do not have the ability to interact with visitors, for example, the user submits a data form, if the form is empty, the browser is not judged, can only be directly submitted to the server side, and then return the null value of the error, so that users can be filled out, which is obviously inefficient and waste resources.

At this time, for Netscape, which is at the forefront of technological innovation, to develop a practical client-script language to deal with these problems became necessary, so the task fell to the engineer Brendan Eich body. He felt it, wood necessary design is very complex, as long as can handle some simple operation is enough, such as to determine whether the user has filled out the form.

1994 is the flourishing era of object-oriented programming (object-oriented programming), C + + is the most popular language, and the Java language version 1.0 will be introduced the following year, Brendan Eich unavoidably affected by it, He wants to think of all the data types in JavaScript as objects (object), which is very similar to Java. However, he immediately encountered a problem, whether or not to design the "inheritance" mechanism?

Ii. origin and evolution of inheritance

1, using the new keyword to generate an example

Working with form validation this simple scripting language obviously does not require an "inheritance" mechanism, but if JavaScript is an object, there is a way to connect all objects. Finally, Brendan Eich still designed "inheritance." It's just that he didn't introduce the concept of class, because JavaScript is a complete object-oriented programming language once you have a "class".

This seems a bit too formal, and the design of the original intention is also far, while increasing the beginner's difficulty in getting started.

References to C + + and the Java language Use the new command to generate an instance:

C + + writes this:

ClassName *object = new ClassName (param);

Java writes this:

Foo foo = new Foo ();

You can also introduce the new command into JavaScript, which is used to generate an instance object from a prototype object. However, there is no "class" in JavaScript, how to represent the prototype object?

The constructor function (constructor) of the class is invoked when the new command is still referenced in C + + and Java. Brendan Eich simplifies design, in JavaScript language, the new command is followed by a constructor, no longer a class.

For example, there is now a prototype called a WD constructor that represents a front-end development (Web-developper) object.

function WD (skill) {

This.skill = skill;

}

With the new keyword for this constructor, an instance of the front-end development object is generated.

var WD1 = new WD (' HTML ');

Console.log (Wd1.skill); Html

The This keyword in the constructor, which actually represents the newly created instance object.

2, new out of the object of the defect

Using the new keyword, generating instance objects with constructors cannot share properties and methods.

For example, in a WD object's constructor, set a common property skill for an instance object.

function WD (skill) {

This.skill = skill;

This.sex = ' Male ';

}

Then, two instance objects are generated:

var WD1 = new WD (' HTML ');

var WD2 = new WD (' CSS ');

The skill property of the two objects is independent, and modifying one does not affect the other.

Wd1.skill= ' Javascript ';

Console.log (Wd2.skill);//"CSS", unaffected by WD1

Each instance object has its own copy of the properties and methods. This not only can not do data sharing, but also a huge waste of resources.

3, the introduction of prototype properties

To implement the sharing of properties and methods, Brendan Eich decides to set a prototype property for the constructor.

This property contains an object (hereinafter referred to as "prototype object") in which all instance objects need to be shared properties and methods, all of which are placed inside the object, and those that do not need to be shared are placed inside the constructor.

Once the instance object is created, the properties and methods of the prototype object are automatically referenced. That is, the properties and methods of an instance object are divided into two types, one local and the other referenced.

Or as an example of a WD constructor, now overwrite with the prototype property:

function WD (skill) {

This.skill = skill;

}

Wd.prototype = {sex: ' Male '};

var WD1 = new WD (' HTML ');

var WD2 = new WD (' CSS ');

Console.log (Wd1.sex); Man

Console.log (Wd2.sex); Man

Now, the sex attribute is placed in the prototype object and is shared by two instance objects. As long as the prototype object is modified, it affects two instance objects at the same time.

WD.prototype.sex = ' female ';

Console.log (Wd1.sex); Woman

Console.log (Wd2.sex); Woman

Since all instance objects share the same prototype object, the prototype object looks like the prototype of the instance object from the outside, and the instance object seems to "inherit" the prototype object. This is the design idea of the JavaScript inheritance mechanism.

Iii. How constructors Implement inheritance

There is now a constructor for an "MED" Object (med:marketing experience design, marketing experience)

function MED () {

This.aim = "Marketing experience Design";

}

is still the constructor of the "WD" object,

function WD (skill,sex) {

This.skill = skill;

This.sex = sex;

}

How can we make "WD" Inherit "MED"?

1. Apply binding constructor implementation

The simplest method, presumably, is to use the call or Apply method to bind the parent object's constructor to a child object, which is to add a row to the child object constructor:

function WD (skill,sex) {

Med.apply (this, arguments);

This.skill = skill;

This.sex = sex;

}

var WD1 = new WD ("Html", "male");

Console.log (Wd1.aim); "Marketing Experience Design"

2. Prototype Mode implementation

Our usual practice is to use the prototype property. If the prototype object of "WD" points to an instance of Med, then all instances of "WD" can inherit Med.

Wd.prototype = new Med ()//We point the prototype object of WD to an instance of Med.

WD.prototype.constructor = WD;

var WD1 = new WD ("Html", "male");

Console.log (Wd1.aim); Marketing Experience Design

This sentence

Wd.prototype = new MED ();

This is equivalent to completely removing the original value of the prototype object and then assigning a new value. So what does the second line mean?

WD.prototype.constructor = WD;

It turns out that any prototype object has a constructor property that points to its constructor. That is to say, Wd.prototype the object's constructor attribute, pointing to WD.

We have deleted the original value of this prototype object in the previous step, so the new prototype object has no constructor attribute, we need to add it manually, otherwise the "inheritance chain" will go wrong. That's what the second line means.

Note that this is a very important point to be sure to follow in programming, as follows, that is, if you replace the prototype object,

O.prototype = {};

The next step, then, is necessarily to add the constructor attribute to the new prototype object and refer back to the original constructor.

O.prototype.constructor = O;

3. Direct inheritance from prototype implementation

Because of the Med object, the invariant properties can be written directly to the Med.prototype. So, we can also let WD () skip MED () and inherit Med.prototype directly.

Now, let's rewrite the Med object:

function MED () {}

MED.prototype.skill = "MED";

Then, the prototype object of WD points to the Med prototype object, which completes the inheritance.

Wd.prototype = Med.prototype;

WD.prototype.constructor = WD;

var WD1 = new WD ("Html", "male");

Console.log (Wd1.skill); MED

Compared to the previous method, the advantage of this is that it is more efficient (do not need to execute and establish an instance of the Med), compared to save memory. The disadvantage is that Wd.prototype and Med.prototype now point to the same object, and any changes to Wd.prototype will be reflected in Med.prototype.

So, the above section of code is actually problematic. Please look at the second line

WD.prototype.constructor = WD;

This sentence actually put the Med.prototype object's constructor attribute also to get rid of!

Console.log (MED.prototype.constructor); Wd

4. Use an empty object as an intermediary to implement

Because of the above disadvantages of "direct inheritance prototype", an empty object can be used as an intermediary.

var F = function () {};

F.prototype = Med.prototype;

Wd.prototype = new F ();

WD.prototype.constructor = WD;

F is an empty object, so it hardly takes up memory. At this point, modify the WD prototype object, will not affect the prototype object of the Med.

Console.log (MED.prototype.constructor); MED

5. The encapsulation function using prototype mode

We encapsulate the above method into a function that is easy to use.

function extend (child, Parent) {

var F = function () {};

F.prototype = Parent.prototype;

Child.prototype = new F ();

Child.prototype.constructor = child;

}

When used, the method is as follows

Extend (wd,med);

var WD1 = new WD ("Html", "male");

Console.log (Wd1.aim); Marketing Experience Design

This extend function is the Yui library how to implement the method of inheritance.

6. Copy Inheritance Implementation

The above is a prototype way to implement inheritance. In fact, since the child object will have the parent object's properties and methods, we directly use the "copy" method can also achieve the effect. Simply put, if you copy all the properties and methods of a parent object into a child object, can you not inherit it?

First, all the invariant properties of Med are placed on its prototype object.

function MED () {}

MED.prototype.aim = "Marketing experience Design";

Then, write a function that implements the purpose of the property copy.

function extendcopy (Child, Parent) {

var p = parent.prototype;

var c = Child.prototype;

for (var i in P) {

C[i] = P[i];

}

}

The function is to copy the properties of the parent object's prototype object, one by one to the prototype object of the child object.

When used, write like this:

Extendcopy (WD, MED);

var WD1 = new WD ("Html", "male");

Console.log (Wd1.aim); Marketing Experience Design

How to implement the inheritance of "non-constructor"

For example, now there is an object called "MED" – The marketing experience design.

var MED = {

Aim: ' Marketing experience design '

}

There is also an object called "Front-End development."

var WD ={

Skill: ' HTML '

}

How can I let "front-end development" to inherit "marketing experience design", that is, how can I generate a "marketing experience design Front-End development" object?

Notice here that both objects are normal objects, not constructors, and cannot be implemented with the constructor method.

1. Object () method

The JSON-formatted inventor Douglas Crockford, presents an object () function that can do this.

function Object (o) {

function F () {}

F.prototype = O;

return new F ();

}

This object () function, in fact, only do one thing, that is, the object of the prototype attribute, point to the parent object, so that child objects and the parent object together.

When used, the first step is to generate child objects on the basis of the parent object:

var WD = object (MED);

Then, plus the properties of the child object itself:

Wd.skill = ' html ';

At this point, the child object has inherited the properties of the parent object.

Console.log (Wd.aim); Marketing Experience Design

2, Shallow copy

In addition to using the "prototype chain", there is another idea: the parent object's attributes, all copied to the child object, can also implement inheritance.

The following function is making a copy:

function Lightcopy (p) {

var c = {};

for (var i in P) {

C[i] = P[i];

}

C.uber = p;

return C;

}

When used, write like this:

var WD = lightcopy (MED);

Wd.aim = ' Front-End development ';

However, there is a problem with such a copy. That is, if the parent object's properties are equal to an array or another object, the child object actually gets only a memory address, not a real copy, so there is a possibility that the parent object has been tampered with.

See, now add a "skill" attribute to Med, whose value is an array.

Med.skills = [' html ', ' CSS ', ' Javascript '];

Through the Lightcopy () function, WD inherits the Med.

var WD = lightcopy (MED);

Then, we add a property for WD's "skills":

WD.skills.push (' teamwork ');

What happened? Med's "skills" have also been tampered with!

Console.log (Wd.skills); ' HTML ', ' Javascript ', ' css ', ' teamwork '

Console.log (Med.skills); ' HTML ', ' Javascript ', ' css ', ' teamwork '

So, lightcopy () just copies the basic type of data, and we call this copy "shallow copy." This is how early jquery implements inheritance.

3, deep copy

The so-called "deep copy" is the ability to achieve the true meaning of the array and the copy of the object. Its implementation is not difficult, as long as the recursive call "shallow copy" on the line.

function Deepcopy (p, c) {

var c = C | | {};

for (var i in P) {

if (typeof p[i] = = = ' object ') {

C[i] = (P[i].constructor = = Array)? [] : {};

Deepcopy (P[i], c[i]);

} else {

C[i] = P[i];

}

}

return C;

}

When used, write this:

var WD = deepcopy (MED);

Now, add a property to the parent object, and the value is an array. Then, modify the property on the child object:

Med.skills = [' html ', ' CSS ', ' Javascript '];

WD.skills.push (' teamwork ');

At this point, the parent object will not be affected.

Console.log (Wd.skills); ' HTML ', ' CSS ', ' Javascript ', ' teamwork '

Console.log (Med.skills); ' HTML ', ' CSS ', ' Javascript '

Currently, the jquery library is using this inheritance method.

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.