From Mixin to new and prototype:javascript the prototype mechanism is detailed

Source: Internet
Author: User

This is an article in the markdown format, a better reading experience please visit my github, mobile end please visit my blog

Inheritance is to achieve the reuse of methods, how to achieve the reuse of the method? The easiest thing to think about is:

"JS
Mixin
function extend (optional, base) {
For (var prop in base) {
if (!prop in optional) {
Optional[prop] = Base[prop]
}
}

Return optional
}
```

This method is commonly known as ' mixin ', it directly from the object copy methods and properties and methods to the B object, B object has the function of a object, simple and rough, easy to understand. But it has a drawback, is that performance is low, wasted space, because each time the expansion to be copied over. So, is there a more elegant way to inherit?

Of course.

In fact, ' Javascript ' naturally incorporates a more elegant and simple approach, which is known as the ' prototype ' prototype chain mechanism, and the content of this mechanism can be described as:

> Inside each object is a ' [[Prototype] ' property, which is a pointer to an object that is not found when it is evaluated, and attempts to find it from the object pointed to by the pointer (that is, the object's prototype), if it has not been found, will continue the prototype of its prototype to find, the process will continue until the end--' object.prototype '.

can also be simply illustrated as:

! [prototype backtracking mechanism] (http://i1.piimg.com/4851/1955da266d428cc5.png)

This method of object extension is very refreshing, if you want the B object to extend the method from the object, as long as the ' [[prototype] ' property of the B object is pointed directly to the object. That is to say, the ' prototype ' mechanism is a method multiplexing implementation at the object level, and its thought is simple. In a classic class-inheriting language, implementing inheritance requires creating a parent class, then creating a subclass that inherits the parent class, and then instantiates the subclass.

```
Pseudo code
Class a{}
Class B extends a{}
b foo = new B ()
```
Amazingly, while the prototype mechanism is the cornerstone of ' Javascript ' inheritance, ' JavaScript ' didn't provide a ' [[prototype] ' pointer to another object before ' ECMAScript5 ' was released. API ', instead of simulating the syntax of a typical class language in a very strange way, known as constructors and ' new '. Constructors and ' new ' nicely satisfy some programmers ' quest for classic class syntax, but it obscures a lot of details and principles that can be misleading, for the moment, not the table.

To implement a purely ' Javascript ' prototype inheritance, it is essential to directly set the ' [[[prototype]] ' pointer ' API '. Some browsers have exposed a readable writable ' __proto__ ' property to the object, which can be used to set the ' [[prototype] ' pointer of the object, and ' ES5 ' finally provides a ' object.create () ' method for setting ' [[prototype] ] ' pointer.

Using the ' object.create () ' method, you can easily implement pure ' Javascript ' inheritance, for example:

"JS
var person = {
Speak:function (what) {
Console.log (what)
}
}
var artist = object.create (person)

I am an Artist
Artist.speak (' I am an artist ')
```

The ' Artist ' object is created by ' object.create ', so its internal ' [[prototype] ' pointer points to ' person ', which is not found on itself when we query its ' speak ' property. Then it automatically goes to its prototype to inquire. The entire process can be illustrated as follows:

! [Archetypal inheritance of person and artist] (http://i1.piimg.com/4851/26abcfa8784c844c.png)

This is a lightweight, concise, easy to understand inheritance, we can casually create a new ' Artist ' object, let it inherit ' person ', if you need to add a new method to all ' artist ', just add the ' person ' to take effect immediately.

But this simple mechanism is not without its drawbacks. The attributes on ' person ' are shared by all ' artist '. In the real world, every ' artist ' has some unique attributes that can't be shared with others, such as his name, genre, masterpiece, and so on, so my code might change to this:

"JS
Public properties are written on the prototype
var person = {
Speak:function () {
Return this.name
}
}

Creating objects
var artist = object.create (person)

Own properties
Artist.name = ' Leonardo da Vinci '
Artist.school = ' Classical '
Artist.works = [' Mona Lisa ']

```

However, each time a ' artist ' object is created to write such a large string, we'd better wrap the creation process in a function that:

"JS
var person = {
Getname:function () {
Return this.name
}
}

function genartist (name, school, work) {
Set up prototypes
var artist = object.create (person)

Its own properties
Artist.name = Name
Artist.school = School
Article.work = Work

return artist
}

var Vinci = genartist (' Leonardo da Vinci ', ' classical ', ' Mona Lisa ')

Leonardo da Vinci
Console.log (Vinci.speak ())
```

Now each time a new ' artist ' is created through the ' genartist ' function, the returned object will both generate its own unique property and inherit the property of ' person '. Because the ' [[prototype] ' of the newly generated object points to the ' person ' object. The entire ' genartist ' function is a production of ' artist ' object of the __ factory __, this process can be illustrated as follows:

! [Artist Factory] (http://i1.piimg.com/4851/66ad74bb1dc6b3d3.png)

At this point we have created a fairly satisfying pure ' Javascript ' approach to object generation: by using functions to generate a class of objects, the generated objects share the prototype method, and if we want to, we can also put ' person ' ' [[prototype] ' to another object, Extend the prototype chain.

But this method also has a disadvantage, we can not use the ' instanceof ' operator to detect which category it belongs to, ' instanceof ' detection principle is:

> returns ' true ' if a function's ' prototype ' pointer points to an object that is the same as any object on the prototype chain of an object.

! [instanceof Principle of detection] (http://i1.piimg.com/4851/ca1b5fe9e9b5ddc6.png)

The ' [[prototype] ' of the object generated by the factory function method is specified as a different object, ' person ', and there is no ' prototype ' pointing to which function, so ' instanceof ' is not available. Then we'd better specify. (Note that the ' prototype ' pointer to the __ function here is very easy to confuse with the ' [[prototype] ' pointer __ of the __ object, which is a property of each function object, and acts as an object that comes out of this function ' new ') [[ Prototype]] ' pointer to the target. )

"JS
function Artist (name, school, work) {
Important
var artist = object.create (Artist.prototype)

Artist.name = Name
Artist.school = School
Artist.work = Work

return artist
}

var artist = artist ()
Console.log (artist instanceof artist)//true
```

Now the generated object's ' [[prototype] ' points to the ' prototype ' of the function ' Artist ', and ' instanceof ' is finally ready to use. The problem comes again: ' Person ' is lost, and ' person ' has added some common methods to all objects and cannot be discarded. But think, now that all the generated objects ' [[prototype] ' are pointing to ' artist.prototype ', will we just expand on ' Artist.prototype '?

"JS
Artist.prototype.speak = function () {
Return this.name
}
```

At this point, we fully implement all the effects of the ' new ' and the constructors, but the difference is that there is no black box in our implementation, and every step is clear. The above process, with ' new ' and the constructor __ equivalent __ Rewrite, probably like this:

"JS
function Artist (name, school, work) {
THIS.name = Name
This.school = School
This.work = Work
}

var artist = new Artist ()

Console.log (artist instanceof artist)//true
```

! [constructor and new mechanism diagram] (HTTP://PLACEHOLDER.EXP)

Comparing constructors with the previous factory functions, there are several different points found:

1. The ' [[prototype] ' of the generated object is not explicitly specified.

2. An object is not returned.

3. Call to add the keyword ' new '.

This means that the keyword ' new ' calls the function, the back will automatically for you to complete 1, 22 steps, behind the dry so many things, are condensed into a __ ' new ' magic __, it is no wonder that many people confused.

Transfer from CYNICZZZ

From Mixin to new and prototype:javascript the prototype mechanism is detailed

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.