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