深入理解JavaScript的原型对象

上一篇文章(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();   //Jack  
p2.sayName();   //Zhang  

Object.getPrototypeOf(p1) === Person.prototype    //true
Object.getPrototypeOf(p2) === Person.prototype    //true

p1.__proto__ === Person.prototype  //true
p2.__proto__ === Person.prototype  //true
上面都是自解释代码,一看就能明白。通过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的继承:

//定义父类Person,构造函数内有两个属性name和age,原型对象内定义了sayName方法  
function Person(name, age) { 
	this.name = name; 
	this.age = age;
} 
Person.prototype.sayName = function(){ 
	alert(this.name); 
}

//定义子类Man,让其模拟继承父类
Personfunction Man(name, age){ 
	Person.call(this, name, age);  //子类中调用父类的构造函数 
	this.gender = "male";          //子类中定义个新属性gender
}

Man.prototype = new Person();  //继承是通过创建父类的原型对象,并将子类的prototype指针指向该原型对象来实现的
Man.prototype.constructor = Person;
Man.prototype.sayGender = function (){ 
	alert(this.gender); 
};

var m1 = new Man("Jack", 32);
m1.sayName();    //Jack
m1.sayGender();  //male
var m2 = new Man("Zhang", 30);
m2.sayName();    //Zhang
m2.sayGender();  //male

alert(m1 instanceof Object); //true,显然创建的实例对象,既是Object,也是Person,也是Man
alert(m1 instanceof Person); //true
alert(m1 instanceof Man);    //true

alert(Object.prototype.isPrototypeOf(m1));  //true
alert(Person.prototype.isPrototypeOf(m1));  //true
alert(Man.prototype.isPrototypeOf(m1));     //true
 
 
 示意图: 






  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值