当我第一次开始学习JavaScript对象模型,我的感觉就是好深奥啊,好难懂啊。我完全不解其prototype的性质,因为javascript是我第一次遇到的一个基于原型的语言。我不知道JavaScript有一个独特的prototype的作用,构造函数的概念。我相信,许多人都有过类似的经验。

在开发中,javascript使用是非常频繁的,只是简单的学习远远达不到理解的目的,必须渐渐深入它,也行你也会像我一样突然发现自己喜欢上了这样的方式。JavaScript是一门优雅和灵活性的原型语言。基于原型的语言有着更简单,更灵活的对象模型。

原型

在javascript中每个对象都有一个prototype,实例化的javascript对象都有一个proto,如下面代码:

1
2
3
4
5
6
var Person = function(){};
var person1 = new Person();
var person2 = new Person();
console.log(Person.prototype);//object
console.log(person1.__proto__);//object 注:有的浏览器不支持直接读取内部原型。
console.log(person2.__proto__);//object

proto是一个指向prototype的指针。所以他们改变其一也会影响全部(都是修改原型对象)。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
Person.prototype.sayHi = function(){
console.log("Hi javascript");
}
Person.prototype.sayHi();//Hi javascript
person1.__proto__.sayHi();//Hi javascript
person2.__proto__.sayHi();//Hi javascript
person1.__proto__.sayHello = function(){
console.log("Hello javascript");
}
Person.prototype.sayHello();//Hello javascript
person1.__proto__.sayHello();//Hello javascript
person2.__proto__.sayHello();//Hello javascript

原型链

因为原型之间的相互关系,所以会产生原型链。比如person1person2,它的内部原型(proto)指向Person.prototype,Person.prototype中又有proto指向Object.prototype,Object.prototype中proto指向null。

代码验证:

1
2
3
console.log(person1.__proto__ === Person.prototype );//true
console.log(Person.prototype.__proto__ === Object.prototype );//true
console.log(Object.prototype.__proto__ === null );//true

注:如果采用字面量了创建对象,其内部原型(proto)指向Object.prototype。

代码如下:

1
2
var person = {};
console.log(person.__proto__ === Object.prototype );//true

原型链查找

明白了原型链,对于原型链的查找就很容易理解了。查找从最近的向上查找,找到了就返回,否则直至最顶层。

如下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
var Person = function(){
this.name = "faith";
};
var person = new Person();
Person.prototype.name1 = "Person.prototype.name";
Object.prototype.name1 = "Object.prototype.name";
Person.prototype.name2 = "faith2";
Object.prototype.name3 = "faith3";
console.log(person.name);//faith
console.log(person.name1);//Person.prototype.name
console.log(person.name2);//faith2
console.log(person.name3);//faith3

原型链查找的时候如果层数越多必然性能就不好,就和person.hobby.a总慢于person.hobby,因为如果要获得a的值,浏览器必须要解析person.hobby。原型链查找也是一样。

因为电脑上没装导图&&uml软件,所以没有画图,附上Hursh Jain的分析图。
原型图片:来源于mollypages.org

参考文档

  • 《javascript 高级程序设计》第三版。
  • mollypages