Learn a wave of Ruan Yifeng’s blog poke here

Blog is my own understanding, as well as the description of the boss is not clear place for correction, also can be regarded as my own production (TU) out (CAO) bar

One of JavaScript Object Oriented (Wrapper)

Constructor to inherit


Let’s start with an easy one:

function Animal(){
    this.type = 'animal; '
}

functionCat(name, color){this.name = name this.color = color animall. call(this)} var Cat = new Cat(){this.name = name this.color = color'po'.'orange')
console.log(cat.type) //animal
Copy the code

Create a constructor for Animal and Cat, then call the constructor for Animal inside Cat, and instantiate Cat to access Animal properties. This example is obviously problematic and is used to pick a fight in the first place.

What’s the problem? If I want to use a public method on Animal like this.animal.prototype.eat = function(){console.log(‘ Animal eat’)}, I can’t access it with cat.eat().

Why is that? Because Cat and Animal are not related at all. If you look at our code, where is it associated?

Use stereotypes for inheritance


So let’s try to connect the two prototypes

function Animal(){
    this.type = 'animal; '
}
Animal.prototype.eat = function(){ console.log('animal eat')}function Cat(name, color){
    this.name = name
    this.color = color
}

Cat.prototype = new Animal()

var cat = new Cat('po'.'orange')
console.log(cat.type) //animal
console.log(cat.eat()) //animal eat
Copy the code

That’s a good way! You can get properties and methods, kill two birds with one stone. But there is a catch (keng)!! Cat. Prototype = new Animal(), all methods in Cat. Prototype are gone! What’s going on here? Because new, new does four things, and here’s a review:

var temp = {}
temp.__proto__ = Animal.prototype
Animal.call(temp)
return temp
Copy the code

See? New takes an empty object and returns it. Our cat. prototype is thus cleared (including its own constructor). So we need to do one thing the prototype. The constructor = Cat.

If we didn’t, what would be the constructor of cat.prototype? The second thing new does is that the null object points to animal. prototype, so Cat. Prototype itself would look for animal. prototype if it didn’t have its constructor property. Cat.prototype.constructor === Animal //true

So, if we replace Prototype, we need to correct it manually.

Inherit prototype directly


Since the above method is flawed, and it’s really easy for you to miss, let’s improve it:

function Animal(){}
Animal.prototype.eat = function(){ console.log('animal eat') }

Cat.prototype = Animal.prototype
Cat.prototype.constructor = Cat

var cat = new Cat('po'.'orange')
console.log(cat.eat()) //animal eat
Copy the code

Since we want to get it from animal.prototype, can’t we just get it from the top? And I also tactfully filled in the holes that would appear above. And the result is what I want.

But!!!!! Our cat. prototype and animal. prototype point to the same prototype, which causes something I did on cat. prototype to happen to animal. prototype at the same time. Why is that? MDZZ, these two are the same thing, the prototype is a piece of memory in the heap, Cat and Animal are pointing to this piece of memory, operating on the same thing, how can it not affect?

Meanwhile, smart-aleck filling holes of the prototype. The constructor = Cat, Cat at this time and the prototype of the Animal is the same, after modified the constructor, lead to Animal constructor turned into a Cat. This method decisively passes…

Use empty objects as mediations


var F = function(){}
F.prototype = Animal.prototype
Cat.prototype = new F()
Cat.prototype.constructor = Cat
Copy the code

We overdo it with intermediate objects and cleverly decouple cat. prototype from animal. prototype so we don’t have problems. A closer look will show that this is similar to what New is doing.

Let’s encapsulate it and use it

function extend(Child, Parent) {
    var F = function() {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; } extend(Cat,Animal); var cat1 = new Cat('po' 'orange');
alert(cat1.eat()); // animal eat
Copy the code

Here child.uber = Parent. Prototype means something like __proto__.

Copies of the inheritance


Here’s another way to do it in a crude way

function extend2(Child, Parent) {
    var p = Parent.prototype;
    var c = Child.prototype;
    for (var i in p) {
        c[i] = p[i];
    }
    c.uber = p;
}

function Animal(){}
Animal.prototype.eat = function(){ console.log('animal eat') }

extend2(Cat, Animal);
var cat1 = new Cat('po' 'orange');
alert(cat1.eat()); // animal eat
Copy the code

Directly traverses the parent class of the prototype, one copy to the child class of the prototype.

Sigh, big guy or big guy ah…