Animal pseudo-class consists of one sit method and two properties: function Animal(name) { this.name = name } Animal.prototype = { canWalk: true, sit: function() { this.canWalk = false alert(this.name + ' sits down.') } } var animal = new Animal('Pet') // (1) alert(animal.canWalk) // true animal.sit() // (2) alert(animal.canWalk) // false new Animal(name) is called, the object gets the link __proto__ to Animal.prototype (see the right part of the schema).animal.sit method changes animal.canWalk in the instance, so our animal can no longer walk, while others can.
prototype use this , which points to the current object, since the value of this depends on the context of the call. Therefore, in animal.sit() this refers to the animal .Animal , for example Rabbit : function Rabbit(name) { this.name = name } Rabbit.prototype.jump = function() { this.canWalk = true alert(this.name + ' jumps!') } var rabbit = new Rabbit('John') Animal - the method is defined in the prototype.Animal , you need to do so Rabbit.prototype.__proto__ == Animal.prototype . This is a natural requirement, since if the method is not found in Rabbit.prototype , we will look for it in the methods of the parent Animal.prototype .
Rabbit.prototype object inherited from Animal.prototype and then add methods. function Rabbit(name) { this.name = name } Rabbit.prototype = inherit(Animal.prototype) Rabbit.prototype.jump = function() { ... } inherit creates an empty object with the specified __proto__ : function inherit(proto) { function F() {} F.prototype = proto return new F } // Animal function Animal(name) { this.name = name } // Animal methods Animal.prototype = { canWalk: true, sit: function() { this.canWalk = false alert(this.name + ' sits down.') } } // Rabbit function Rabbit(name) { this.name = name } // inherit Rabbit.prototype = inherit(Animal.prototype) // Rabbit methods Rabbit.prototype.jump = function() { this.canWalk = true alert(this.name + ' jumps!') } // Usage var rabbit = new Rabbit('Sniffer') rabbit.sit() // Sniffer sits. rabbit.jump() // Sniffer jumps! new Animal for inheritance.Rabbit.prototype = inherit(Animal.prototype) people do the following: // inherit from Animal Rabbit.prototype = new Animal() new Animal in the prototype. Inheritance works, since new Animal naturally inherits Animal.prototype .new Animal() can be called without a name ? A constructor can strictly require arguments and die without them.Animal . We just want to inherit from it.Rabbit.prototype = inherit(Animal.prototype) is preferred. Neat inheritance without side effects.Animal.apply() for the current object: function Rabbit(name) { Animal.apply(this, arguments) } Animal constructor in the context of the current object, and it sets the name instance. Rabbit.prototype.sit = function() { alert(this.name + ' sits in a rabbity way.') } rabbit.sit() sit is searched in the rabbit -> Rabbit.prototype -> Animal.prototype and finds it in Rabbit.prototype before reaching Animal.prototype . rabbit.sit = function() { alert('A special sit of this very rabbit ' + this.name) } Rabbit.prototype.sit = function() { alert('calling superclass sit:') Animal.prototype.sit.apply(this, arguments) } apply/call where the current object is passed as this . A simple call to Animal.prototype.sit() will use Animal.prototype like this .Animal.apply... , or method: Animal.prototype.sit.apply...parent.method() or super() . function extend(Child, Parent) { Child.prototype = inherit(Parent.prototype) Child.prototype.constructor = Child Child.parent = Parent.prototype } function Rabbit(name) { Rabbit.parent.constructor.apply(this, arguments) // super constructor } extend(Rabbit, Animal) Rabbit.prototype.run = function() { Rabbit.parent.run.apply(this, arguments) // parent method alert("fast") } Animal or create an intermediate class GrassEatingAnimal and the changes will affect only Animal and extend(...) .
function Animal() { Animal.count++ } Animal.count = 0 new Animal() new Animal() alert(Animal.count) // 2 function extend(Child, Parent) { Child.prototype = inherit(Parent.prototype) Child.prototype.constructor = Child Child.parent = Parent.prototype } function inherit(proto) { function F() {} F.prototype = proto return new F } // --------- the base object ------------ function Animal(name) { this.name = name } // methods Animal.prototype.run = function() { alert(this + " is running!") } Animal.prototype.toString = function() { return this.name } // --------- the child object ----------- function Rabbit(name) { Rabbit.parent.constructor.apply(this, arguments) } // inherit extend(Rabbit, Animal) // override Rabbit.prototype.run = function() { Rabbit.parent.run.apply(this) alert(this + " bounces high into the sky!") } var rabbit = new Rabbit('Jumper') rabbit.run() mixin(Animal.prototype, { run: ..., toString: ...}) Source: https://habr.com/ru/post/210596/
All Articles