JavaScript原型和继承

发表于:2012-6-01 09:56

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:51Testing软件测试网采编

  五、继承

  有了原型链的概念,就可以进行继承。

function B() {};

  这个时候产生了B的原型B.prototype

  原型本身就是一个Object对象,我们可以看看里面放着哪些数据

  B.prototype 实际上就是 {constructor : B , [[Prototype]] : Object.prototype}

  因为prototype本身是一个Object对象的实例,所以其原型链指向的是Object的原型

B.prototype = A.prototype;//相当于把B的prototype指向了A的prototype;这样只是继承了A的prototype方法,A中的自定义方法则不继承
B.prototype.thisisb = "this is constructor B";//这样也会改变a的prototype

  但是我们只想把B的原型链指向A,如何实现?

  第一种是通过改变原型链引用地址

B.prototype.__proto__ = A.prototype;

  ECMA中并没有__proto__这个方法,这个是ff、chrome等js解释器添加的,等同于EMCA的[[Prototype]],这不是标准方法,那么如何运用标准方法呢?

  我们知道new操作的时候,实际上只是把实例对象的原型链指向了构造函数的prototype地址块,那么我们可以这样操作

B.prototype = new A();

  这样产生的结果是:

  产生一个A的实例,同时赋值给B的原型,也即B.prototype 相当于对象 {width :10 , data : [1,2,3] , key : "this is A" , [[Prototype]] : A.prototype}

  这样就把A的原型通过B.prototype.[[Prototype]]这个对象属性保存起来,构成了原型的链接

  但是注意,这样B产生的对象的构造函数发生了改变,因为在B中没有constructor属性,只能从原型链找到A.prototype,读出constructor:A

var b = new B;
console.log(b.constructor);//output A

  所以我们还要人为设回B本身

B.prototype.constructor = B;
  //现在B的原型就变成了{width :10 , data : [1,2,3] , key : "this is A" , [[Prototype]] : A.prototype , constructor : B}
  console.log(b.constructor);//output B
  //同时B直接通过原型继承了A的自定义属性width和name
  console.log(b.data);//output [1,2,3]
  //这样的坏处就是
  b.data.push(4);//直接改变了prototype的data数组(引用)
  var c = new B;
  alert(c.data);//output [1,2,3,4]
  //其实我们想要的只是原型链,A的自定义属性我们想在B中进行定义(而不是在prototype)
  //该如何进行继承?
  //既然我们不想要A中自定义的属性,那么可以想办法把其过滤掉
  //可以新建一个空函数
  function F(){}
  //把空函数的原型指向构造函数A的原型
  F.prototype = A.prototype;
  //这个时候再通过new操作把B.prototype的原型链指向F的原型
  B.prototype = new F;
  //这个时候B的原型变成了{[[Prototype]] : F.prototype}
  //这里F.prototype其实只是一个地址的引用
  //但是由B创建的实例其constructor指向了A,所以这里要显示设置一下B.prototype的constructor属性
  B.prototype.constructor = B;
  //这个时候B的原型变成了{constructor : B , [[Prototype]] : F.prototype}

  图示如下,其中红色部分代表原型链:

  作为初学者浅陋的理解,本文目的在于更具象地去理解js的面向对象,疏漏之处请指正。

33/3<123
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号