2. PROTOTYPE OF FUNCTION
Every function is born with a prototype object, it’s used as the shared
prototype(parent) of the objects created by this function( invoked as constructor
function).
The prototype is initially an empty object, you can add members to it. Such all its
“children” have access to these members( properties, methods ) as well.
F
prototyp
e
constructo
r
F.prototype
F.prototype.constructor
3. PROTOTYPE OF OBJECT
Every Object is born referencing to a prototype object(parent) by a secret property
__proto__.
__proto__
5. var Person = function(name, age){
this.name = name;
this.age = age;
};
Person.prototype.sayMyName = function(){
console.log("I'm " + this.name);
};
var linus = new Person('Linus Torvalds');
linus.sayMyName();
CONSTRUCT A NEW OBJECT
Person
prototyp
e
constructo
r
__proto__
linus.sayMyName
sayMyNamename: Linus
Torvaldsage: 46
name: Alice
age: 17
name: Bob
age: 18
new
let’s walk through the following simple
code to understand the whole process
there’re 3 steps are done by the
javascript engine whenever a new
instance is created, let’s see them in
action:1. create a bare object
2. create a link “__proto__” points to the
prototype of the constructor function
3. execute the function body of the
constructor function
8. RESOLVE PROPERTY
var value = anObject.someProperty;
Object
prototyp
e
constructo
r
F1
prototyp
e
constructo
r
__proto____proto__
built-
in
F2
prototyp
e
constructo
r
__proto__
anObject
Lookup “someProperty” on
anObject
1
2
b
not found, continue
lookup “someProperty” on
its __proto__ object
found, return
value
2a
found, return
value
3a
3
b
not found, continue
lookup “someProperty” on
its __proto__ object
found, return
value
4a
found, return
value
5a
4
b
not found, continue
lookup “someProperty” on
its __proto__ object
5
b
not found, return
undefined
let’s see how javascript engine resolve
property lookup
9. MODIFY PROPERTY
anObject.someProperty = “some property”;
Object
prototyp
e
constructo
r
F1
prototyp
e
constructo
r
__proto____proto__
built-
in
F2
prototyp
e
constructo
r
__proto__
somePropert
y
somePropert
y
anObject
When you do changes to a property of
an object, it always affect the current
object only. If the property doesn’t
exist, property is added to the object. It
won’t look up to the prototype chain.
11. WRONG PSEUDO-CLASSICAL
INHERITANCE
Develope
r
prototyp
e
constructo
r
__proto__
Person
prototyp
e
constructo
r
new
Develope
r
prototyp
e
constructo
r
__proto__
Person
prototyp
e
constructo
r
F
prototyp
e
new
wrong
correc
t
let’s look at a frequent mistake of doing classical
inheritance
Why is the first example is wrong ? Well, I
wouldn’t say it’s always wrong, but in
most cases, it’s wrong. Because the
subclass Developer’s prototype is an
instance of Person Class, that means it’s a
special individual person. And in most
case, the Person Constructor would
require some arguments to initialize a
Person instance, such as: name, age … Do
we want these properties on the prototype
of Developer ? No ! What we want is a bare
object which just has a “__proto__” points
to the prototype of Person Class. That’s
exactly how the second example does.
Through a temporary constructor function
F which does nothing in its constructor, it
will create a bare object points to the
prototype of F which is equal to prototype
12. OBJECT.CREATE
In ES5, a method is included to implement inheritance:
// utility function for inheritance
var inherit = function(proto){
function F(){}
F.prototype = proto;
return new F();
};
our simple version
Object.create
ES5 version, more
powerful
13. PROTOTYPAL INHERITANCE
Develope
r
Person
__proto__
let’s walk through the following code to see how
prototypal inheritance is achieved
linus
__proto__
That’s it, we accomplished prototypal inheritance. You
can see how much easier prototypal inheritance is than
Classical inheritance. That’s because it completely
discard Constructor parts. And more importantly, in
javascript, the essence of inheritance is through the
“__proto__” link between objects, aka. prototype chain.
At the heart of the classical inheritance, it’s also using
the prototype chain achieving inheritance. Only it add
an extra layer of “Constructor” to simulate the “Class”
concept from other language: java, c#... to make it more
comfortable for developers from those languages. Even
it feels somehow comfortable at first, but without truly
understanding of the essence of prototypal inheritance,
You’ll get lost and confused at last !!! So that’s why a lot
of javascript gurus advocate prototypal inheritance and
recommend avoid using of classical inheritance.
14. __PROTO__ OF FUNCTION
Every function is a “child” of Function.prototype
F
prototyp
e
constructo
r
__proto__
Function
prototyp
e
constructo
r
function
Empty(){}
Object
prototyp
e
constructo
r
__proto__
__proto__
__proto__
ne
w
__proto__
built-
in
built-
in
15. JAVASCRIPT OBJECT LAYOUT
This is a graph of object layout I grab it
from some online website. If you
understand the prototype concept
correctly, you can easily understand the
graph. But personally, I feel it’s a little
messy with all the arrows floating around.
Anyway, it’s a great graph for your
reference when you forget the
relationship.
16. THE END
Thank you for watching!
Author: Jun Shen
I’m an enthusiast about javascript
Javascript Rocks!!!
linked in: https://www.linkedin.com/in/jun-shen-55b01959
Hinweis der Redaktion
You can think of the prototype object is equal to super class at some degree
var Person = function(name, age){
this.name = name;
this.age = age;
};
Person.prototype.selfIntroduce = function(){
return "I'm " + this.name + ", " + this.age + " years old.";
};
// utility function for inheritance
var inherit = function(proto){
function F(){}
F.prototype = proto;
return new F();
};
var Developer = function(name, age, language){
Person.call(this, name, age);
this.language = language;
};
// Developer's prototype to inherite from Person's prototype
Developer.prototype = inherit(Person.prototype);
Developer.prototype.constructor = Developer;
var jun = new Developer('sj', 30, 'javascript');
jun.selfIntroduce();
Don't create new Animal to inherit it
There is a well-known, but wrong way of inhereting, when instead of Rabbit.prototype = inherit(Animal.prototype) people use:
// inherit from Animal
Rabbit.prototype = new Animal()
As a result, we get a new Animal object in prototype. Inheritance works here, becausenew Animal naturally inherits Animal.prototype.
… But who said that new Animal() can be called like without the name? The constructor may strictly require arguments and die without them.
Actually, the problem is more conceptual than that. We don’t want to create an Animal. We just want to inherit from it.
That’s why Rabbit.prototype = inherit(Animal.prototype) is preferred. The neat inheritance without side-effects.
var person = {
selfIntroduce: function(){
return "I'm " + this.name + ", " + this.age + " years old.";
}
};
// prototypal inherite from person
var developer = Object.create(person);
// create an instance of developer
var jun = Object.create(developer);
jun.name = 'jun';
jun.age = 30;
jun.selfIntroduce();