OOP in Javascript

Source: Internet
Author: User
Tags naming convention

Write a few things to get started with Vue, write some other relaxation today and simply talk about the objects in JavaScript.

In the object-oriented language, there are classes of the concept, of course, ES6 in the beginning of JavaScript also has the concept of class, here to ES5 as the basis to begin to explain, after all, even if the current ES6 code is written, usually through the Babel and other transcoding to es5 to execute;

In JS, although there is no concept of class, but we can create objects, generally create objects in two ways (this refers to custom objects):

1. Using constructors

function Person () {} var p=New person ();

2. Use literal

var p={    // various properties }

Here is the emphasis on the constructor to create the object, in the above code, for example, function person () {}, what is the difference between this and the normal function? In fact, in addition to the naming convention (the proposed initial capitalization) of the declaration there is no difference, mainly the invocation of different ways, the constructor call using the new operator, using the new operator to call the constructor, mainly through four steps:

1), create a new object;

2), point this to the new object;

3), adding attributes to the object

4), return new object

Make a few simple changes to the code above:

function Person () {   this.name=  "Zhangsan";    this. age=10;  }; var p=New person (); Console.log (p.name,p.age); //

It is not easy to understand the result of the output by comparing the process of invoking the constructor with the new operator.

Just now, the constructor and the normal function call are exactly the same, so is it possible to make a normal call to the constructor function? Of course, we'll make another modification to our example:

function Person () {   this.name=  "Zhangsan";    this. age=10;  }; // var p=person (); Person (); Console.log (window.name,window.age); //

Do not use the new operator call, do not go through the implicit processing of the above four steps, so this time there will be no new object creation and this direction of the change, then this point to the global object, in the browser is the Window object, So you can use Window.name to access and get the correct output.

Three major features of OOP: encapsulation, inheritance, polymorphism; this is just about how inheritance is done in JavaScript (limited to ES5).

Inheritance is just a means of code reuse, then how to implement inheritance in JS?

Prototype-based inheritance

First, the function is also an object, because all functions are instances of function objects, function names, which define functions as a shortcut, theoretically and var function name = new function (p1,body) equivalent, From this point of view the function name is actually a pointer to the function, but the difference is that through the new function to create functions, will be interpreted by the JS interpreter two times, once is declared, the second is the body part of the resolution.

Second, after any function is created, there is a prototype object, such as:

Declare a person function, then we can use Person.prototype to print its prototype object, we can see its prototype object is an object type, including a property (not __proto__, the term internal variables, is an instance to the prototype pointer) constructor, pointing to the function person, and the prototype object itself is an instance of another object (this is an instance of the object function, =new object ()), and any instance of an object contains an internal variable __proto__ (Chrome browser) (except for objects created with object.create (null)), pointing to the prototype of the type that created the object instance, here __prop__ The point is object.prototype. And you can see several methods (ToString, valueof, and so on) that are included on the Object.prototype.

It says that an instance of any object contains an internal variable that points to its constructor prototype, so we create an instance of the person:

You can see the same one, so we can summarize the relationship between constructors, instances, and constructor prototypes as follows:

Although the painting is very difficult to see, but I think it should also express my intention to express, Ah,??。

In summary, the prototype of the constructor is an object, by default, the object is an instance of the object, and as a result of access, the lookup rule is to find the instance property of the current object first, or, if found, to find a property of the same name on the prototype object pointed to by __proto__. Otherwise, the __proto__ of the prototype object on the object pointing to the same name property, until the __proto__ of an object instance, that is Object.prototype, the link constructed by __proto__ is called the prototype chain.

Take a look at the following code:

functionPerson () { This. Name= "Zhangsan";  This. myfriends=["Zhangsan", "Lisi"]}person.prototype.getname=function(){   return  This. Name; }functionStudent () {}student.prototype=NewPerson ();vars1=NewStudent ();varS2=NewStudent (); S1.myFriends.push ("Wangwu"); Console.log (s1.myfriends);??Console.log (s2.myfriends);??

The above code I implemented a simple inheritance based on the prototype pattern, so what is the above output? It is possible to test and find out that the output is all ["Zhangsna", "Lisi", "Wangwu"]; why does this result, we can not be difficult to analyze, we have the student constructor of the prototype re-designated new objects, So at this point the object (person instance) becomes the prototype object of the student constructor, then its instance property becomes the prototype property of the student constructor, so we have a share when we access the property of the reference type in its prototype through the student instance. , and the above output appears.

This output structure is inconsistent with our expectations, how to deal with this problem, according to our search rules, if we find the corresponding property on this object, not to find the prototype object, based on this, we just overwrite the prototype object, and the simplest way is to borrow the constructor, modify our code as follows:

functionPerson () { This. Name= "Zhangsan";  This. myfriends=["Zhangsan", "Lisi"]}person.prototype.getname=function(){   return  This. Name; }functionStudent () {Person.call ( This);//The key call, note here is the normal call, the non-constructor call, the call, and the change of this by calling this point to the instance of student}student.prototype=NewPerson ();vars1=NewStudent ();varS2=NewStudent (); S1.myFriends.push ("Wangwu"); Console.log (s1.myfriends);Console.log (s2.myfriends);

Using a common method call, passing this, and then dynamically creating the name and Myfriends properties on this, so that the instance does not look for properties on the prototype at output, and resolves the problem that the output does not meet the expectations.

But what is the problem with the above code analysis carefully?

1), Student.prototype.constructor point to Person

2), call the person method two times, one is a constructor call, one is a normal call

3), borrowing a constructor, is creating a new instance property that overrides the prototype property, which creates additional properties.

Modify our code again to deal with the above problem:

functioninherit (child,parent) {functionF () {} F.prototype=parent.prototype;//as long as the content on the prototype, not the instance, avoids the attributes on the instance, inheriting only the properties on the prototype (method)F.prototype.constructor=child;//here is the forced modification of the constructor property, which points to the subtypeChild.prototype=F.prototype;}functionPerson () { This. Name= "Zhangsan";  This. myfriends=["Zhangsan", "Lisi"]}person.prototype.getname=function(){   return  This. Name; }functionStudent () {Person.call ( This);//The key call, note here is the normal call, the non-constructor call, the call, and the change of this by calling this point to the instance of student     }//student.prototype=new person ();inherit (Student,person)vars1=NewStudent ();varS2=NewStudent (); S1.myFriends.push ("Wangwu"); Console.log (s1.myfriends); Console.log (s2.myfriends) ;

Of course the above code is still some imperfect, first Student.prototype.constructor, should be non-enumerable, we are here but can. There are a lot of details that may not be considered, the details of the recommended people to chew on the "JavaScript Advanced Programming" This Bible, this is so much.

OOP in Javascript

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.