上一篇文章(JavaScript对象创建模式http://blog.csdn.net/hongse_zxl/article/details/44595809)介绍了JavaScript的对象创建的模式,其中简单介绍了原型对象。
JavaScript的继承机制是基于原型,而不是类。因此要理解JavaScript的继承机制,需要更深入了解原型对象。
先区分一下基于原型的常见写法:
这3种写法prototype,getPrototypeOf和__proto__之间的不同:
C.prototype:用于引用new C()创建的对象的原型对象
Object.getPrototypeOf(obj):是获取obj对象的原型对象的标准方法
obj.__proto__:是获取obj对象的原型对象的非标准方法
示意代码:
- function Person(name, age) {
- this.name = name;
- this.age = age;
- }
- Person.prototype.sayName = function(){
- alert(this.name);
- }
-
- var p1 = new Person("Jack", 32);
- var p2 = new Person("Zhang", 30);
- p1.sayName();
- p2.sayName();
-
- Object.getPrototypeOf(p1) === Person.prototype
- Object.getPrototypeOf(p2) === Person.prototype
-
- p1.__proto__ === Person.prototype
- p2.__proto__ === Person.prototype
上面都是自解释代码,一看就能明白。通过C.prototype形式,可以获得原型对象,为之添加属性或方法。ES5环境下通过Object.getPrototypeOf(obj)可以检查现有对象的原型。一些环境提供了非标准的方法检索对象的原型,即特殊的属性__proto__,可以在不支持Object.getPrototypeOf方法时作为权宜之计。
(尽可能用Object.getPrototypeOf,而不要用__proto__,详细原因可以参见《Effective JavaScript》的<Item 31: Prefer Object.getPrototypeOf to __proto__>,简单地说__proto__是非安全的)
如何实现继承呢?
通过原型链来模拟其他OO语言中的继承。先回顾一下上一篇文章中介绍过的构造函数和原型对象和实例对象间的关系:
每个构造函数内部均有一个prototype原型指针,指向该类型的原型对象C.prototype。原型对象C.prototype中包含一个回指向构造函数的指针constructor。这样就实现了构造函数和原型对象间的双向绑定。每个实例对象内部也包含一个指向原型对象C.prototype的指针。
现在用原型链来实现JavaScript的继承:
-
- function Person(name, age) {
- this.name = name;
- this.age = age;
- }
- Person.prototype.sayName = function(){
- alert(this.name);
- }
-
-
- Personfunction Man(name, age){
- Person.call(this, name, age);
- this.gender = "male";
- }
-
- Man.prototype = new Person();
- Man.prototype.constructor = Person;
- Man.prototype.sayGender = function (){
- alert(this.gender);
- };
-
- var m1 = new Man("Jack", 32);
- m1.sayName();
- m1.sayGender();
- var m2 = new Man("Zhang", 30);
- m2.sayName();
- m2.sayGender();
-
- alert(m1 instanceof Object);
- alert(m1 instanceof Person);
- alert(m1 instanceof Man);
-
- alert(Object.prototype.isPrototypeOf(m1));
- alert(Person.prototype.isPrototypeOf(m1));
- alert(Man.prototype.isPrototypeOf(m1));
示意图:
![](https://img-blog.csdn.net/20150325201339301)
![](https://img-blog.csdn.net/20150325201403513)
![](https://img-blog.csdn.net/20150325201342413)