深入剖析Javascript之继承

本文对比了三种JavaScript原型链实现方式:使用Object.extend复制属性、直接赋值原型引用及通过new操作符实现继承。探讨了每种方法的特点及可能引发的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导读:

  今天要讨论的主题是下面3种方案的对比:

  前提:

   代码

  var m1 = function(){}; var m2 = function(){};

  要对比的3种方案是:

   代码

  1>Object.extend( m1.prototype, m2.prototype );2>m1.prototype = m2.prototype;3>m1.prototype = new m2();

  下面对各种方案先预先给予说明:

  1>第一种方案是将m2.prototype该对象中所有成员拷贝(覆盖)到m1.prototype对象中。

  看代码:

   代码

  var m1 = function(){}; var m2 = function(){}; var o2 = new m2(); o2.name = 'qk'; m2.prototype.print = function(){ alert( this.name );} Object.extend( m1.prototype, m2.prototype );

  到此,我们可以想象,m2.prototype中的成员变量print已经拷贝到m1.prototype中,即,凡m1对象便拥有print成员。假如我们试图创建m1的对象,

   代码

  var o1 = new m1();

  则我们可以调用o1.print();但由于m1对象中不存在name属性,故会是undefined。问题在哪?是因为m2.prototype对象的成员中包含了m2的实例变量name,这种设计方案是不合理的(这里只是为了演示所用,现实中是不会出现类似的代码的,下同)。

  2>第二种方案是将m1.prototype对象的指针指向m2.prototype的内存地址。或m1.prototype对象只是m2.prototype对象的一个引用。试图改变m2.prototype内存地址后不会影响m1.prototype对象成员的变化。看代码:

   代码

  var m1 = function(){}; var m2 = function(){}; var o2 = new m2(); o2.name = 'qk'; m2.prototype.print = function(){ alert( this.name );} m1.prototype = m2.prototype;// 改变m2.prototype m2.prototype = {0:0};// 打印 var o1 = new m1(); for( var key in o1 ){ alert( key + '=>' + o1[ key ] );}

  不过,如果对m2.prototype对象的成员进行增加或删除,m1.prototype就会改变。看代码:

   代码

  var m1 = function(){}; var m2 = function(){}; var o2 = new m2(); o2.name = 'qk'; m2.prototype.print = function(){ alert( this.name );} m1.prototype = m2.prototype;// 增加m2.prototype对象的成员。 m2.prototype[0] = 0;// 打印 var o1 = new m1(); for( var key in o1 ){ alert( key + '=>' + o1[ key ] );}

  3>第二种方案是让m1.prototype链式继承m2.prototype的所有成员。即m1.prototype继承m2.prototype,m2.prototype继承Object.prototype.它于第二种方案的不同是,第二种方案中,m1.prototype只是m2.prototype对象的一个引用。只有增加或删除m2.prototype成员才会引起m1.prototype成员的变化。它于第一种方案的不同是,第一种方案中,m1.prototype成员只会增加,不会减少。而这里是链式继承。看代码:

   代码

  var m1 = function(){}; var m2 = function(){}; var o2 = new m2(); o2.name = 'qk'; m2.prototype.print = function(){ alert( this.name );} m1.prototype = new m2();// 打印 var o1 = new m1(); for( var key in o1 ){ alert( key + '=>' + o1[ key ] );}

  此时,o1对象访问属性的顺序是:

  m1.prototype对象成员 >m2的实例变量 >m2.prototype对象成员 >m1的的实例变量

  好了,介绍完这3种“继承”后,希望大家对javascript的prototype的继承有了更深一步的了解!



本文转自

http://j2eeqk.javaeye.com/blog/70028
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值