基本的用法 把ClassA的一个实例赋值给ClassB ClassB就继承了ClassA的所有属性

1 function ClassA(){
2     this.a='a';
3 }
4 function ClassB(){
5     this.b='b';
6 }
7 ClassB.prototype=new ClassA();
8 var objB=new ClassB();
9 for(var p in objB)document.write(p+"<br>");

从原型继承理论的角度去考虑 js的原型继承是引用原型 不是复制原型
所以 修改原型会导致所有B的实例的变化

 1 function ClassA(){
 2     this.a='a';
 3 }
 4 function ClassB(){
 5     this.b='b';
 6 }
 7 ClassB.prototype=new ClassA();
 8 var objB=new ClassB();
 9 alert(objB.a);
10 ClassB.prototype.a='changed!!';
11 alert(objB.a);

然而 子类对象的写操作只访问子类对象中成员 它们之间不会互相影响
因此 写是写子类 读是读原型(如果子类中没有的话)

 1 function ClassA(){
 2     this.a='a';
 3 }
 4 function ClassB(){
 5     this.b='b';
 6 }
 7 ClassB.prototype=new ClassA();
 8 var objB1=new ClassB();
 9 var objB2=new ClassB();
10 objB1.a='!!!';
11 alert(objB1.a);

接下来是致命的,在子类对象中访问原型的成员对象:

 1 function ClassA(){
 2     this.a=[];
 3 }
 4 function ClassB(){
 5     this.b=function(){alert();};
 6 }
 7 ClassB.prototype=new ClassA();
 8 var objB1=new ClassB();
 9 var objB2=new ClassB();
10 objB1.a.push(1,2,3);
11 alert(objB2.a);
12 alert(objB2.a);
13 //所有b的实例中的a成员全都变了!!
14 //所以 在prototype继承中 原型类中不能有成员对象! 所有成员必须是值类型数据(string也可以)

只简单的这样设置继承的确如楼主所说,有不少缺点。总的来说有四个缺点:

  缺点一:父类的构造函数不是像JAVA中那样在给子类进行实例化时执行的,而是在设置继承的时候执行的,并且只执行一次。这往往不是我们希望的,特别是父类的构造函数中有一些特殊操作的情况下。

  缺点二:由于父类的构造函数不是在子类进行实例化时执行,在父类的构造函数中设置的成员变量到了子类中就成了所有实例对象公有的公共变量。由于JavaScript中继承只发生在“获取”属性的值时,对于属性的值是String,Number和Boolean这些数据本身不能被修改的类型时没有什么影响。但是Array和Object类型就会有问题。
  缺点三:如果父类的构造函数需要参数,我们就没有办法了。

  缺点四:子类原本的原型对象被替换了,子类本身的constructor属性就没有了。在类的实例取它的constructor属性时,取得的是从父类中继承的constructor属性,从而constructor的值是父类而不是子类。

1 //类的继承-海浪版
2 Function.prototype.Extends = function (parentClass){
3   var Bs = new Function();
4   Bs.prototype = parentClass.prototype;
5   this.prototype = new Bs();
6   this.prototype.Super = parentClass;
7   this.prototype.constructor = this;
8 }

先来看看用new形式创建对象的过程:

1 //以func()作为构造函数创建一个对象obj
2 var obj=new func();

这个过程是这样的:javascript引擎首先遇到了关键字new后,马上开辟了一块内存,创建了一个空对象(并且将this指向这个对象),接着执行构造函数func()对这个空对象进行构造(构造函数里面有什么属性和方法都一一给这个空白对象装配上去,这也就是为什么构造函数叫“构造函数”的原因)。

其实,new和执行构造函数之间还有一件事引擎没有显式地告诉我们,而是偷偷地做了,这就是给这个空对象赋予prototype对象。

这里不得不提到一个跟prototype一样同样是系统保留而且同样重要的东西:__proto__

__proto__是一个对象自动拥有的内置属性(请注意:prototype是函数的内置属性,__proto__是对象的内置属性,但它们最终都指向同一个对象,就是那个用来被继承的对象),用chrome和FF都可以访问到一个对象的__proto__属性,IE就不可以。

正是一个对象的__proto__指向着这个对象的构造函数的prototype对象,才使这个对象认识了它的构造函数的prototype对象,并拥有了这个prototype对象的属性和方法。

所以var obj=new func()这个过程更具体是这样的:

  1. javascript解析引擎遇到new后,开辟一片内存并创建了一个空对象,并且将“this”指向这个空对象
  2. javascript解析引擎将这个空对象的__proto__指向后面紧跟着的构造函数默认的prototype对象(一指向到prototype对象后,解析引擎就知道了“噢,这个对象要拥有这个prototype对象的属性和方法了”)
  3. javascript解析引擎执行构造函数体内的代码,也就正式开始对这个空对象进行构造(或者说装配)的过程了(this.name="xxx",this.sayHello=function(){...}等等)
  4. 对象被构造装配好,并赋值到等号左边的变量。

转载于:https://www.cnblogs.com/piaozhe116/p/5511594.html

js - prototype 继承相关推荐

  1. js中继承的几种用法总结(apply,call,prototype)

    本篇文章主要介绍了js中继承的几种用法总结(apply,call,prototype) 需要的朋友可以过来参考下,希望对大家有所帮助 一,js中对象继承 js中有三种继承方式 1.js原型(proto ...

  2. js原型继承——prototype的使用

    文章目录 prototype的定义 原型链继承 修改prototype 继承的子类能否覆盖父类属性 总结 一些笔试题 第一题 第二题 小彩蛋 结语 参考文章 prototype的定义 javascri ...

  3. 你真的理解JS的继承了吗?

    噫吁嚱,js之难,难于上青天 学习js的这几年,在原型链和继承上花了不知道多少时间,每当自以为已经吃透它的时候,总是不经意的会出现各种难以理解的幺蛾子.也许就像kyle大佬说的那样,js的继承真的是' ...

  4. (转)js实现继承的5种方式

    js是门灵活的语言,实现一种功能往往有多种做法,ECMAScript没有明确的继承机制,而是通过模仿实现的,根据js语言的本身的特性,js实现继承有以下通用的几种方式 1.使用对象冒充实现继承(该种实 ...

  5. 面试官问:JS的继承

    原文作者若川,掘金链接:https://juejin.im/post/5c433e216fb9a049c15f841b 写于2019年2月20日,现在发到公众号声明原创,之前被<前端大全> ...

  6. Node.js: 如何继承 events 自定义事件及触发函数

    events 是node.js的核心api ,几乎大部分node.js 的api都继承 events 类(javascript中没有类,也不存在继承,确切说是模拟类和继承,点击查看) 比如我们常见的 ...

  7. 学会这5种JS函数继承方式,前端面试你至少成功50%

    摘要:函数继承是在JS里比较基础也是比较重要的一部分,而且也是面试中常常要问到的.下面带你快速了解JS中有哪几种是经常出现且必须掌握的继承方式.掌握下面的内容面试也差不多没问题啦~ 本文分享自华为云社 ...

  8. Js Call方法详解(js 的继承)

    call 方法 请参阅 应用于:Function 对象 要求 版本 5.5 调用一个对象的一个方法,以另一个对象替换当前对象. call([thisObj[,arg1[, arg2[, [,.argN ...

  9. js 原型prototype继承模式

    js中利用原型prototype的方式实现继承是最常见的继承模式,如果让a的实例继承b,原型prototype的继承方式如下: function A(){} function B(){} A.prot ...

最新文章

  1. WCF-Discovery的协议基础:WS-Disvovery(客户端驱动探测服务)
  2. 双十一!教你用Python感知女朋友的情绪变化?
  3. C语言学习之试编程从键盘输入2*3的二维数组,将该数组行列交换输出。
  4. 多进程与多线程的区别
  5. for range 经典问题
  6. Android 开发笔记___drawable
  7. python计算绩效工资_python实现 --工资管理系统
  8. Lesson 6   Smash-and-grab 砸橱窗抢劫
  9. android串口service,Android串口操作库:EZ-SerialPort
  10. 在写易买网时产生的错误 JSTL标签库中c:choose/c:choose不能放JSP页面!-- --注释...
  11. JavaScript 字符串(String)对象
  12. php 3种常见设计模式
  13. Delphi2007卸载
  14. 三星Note3 SM-N9009 国内天翼版本安装谷歌框架
  15. 【数学建模】随机抽样的三种方法(简单随机抽样、分层抽样、系统抽样),自定义封装函数直接调用
  16. 视频网站程序 linux,观看主流视频平台视频的Windows、Mac、Linux客户端:ivideo
  17. 视频和视频帧:图像,从自然光到01串
  18. linux 二次封装 释放,Linux必学的60个命令(二)
  19. 100块钱有多少组成方式
  20. Postman实现接口自动化测试

热门文章

  1. 【模拟退火】解决【TSP】问题
  2. floodFill函数
  3. opencv Remap 图像的映射
  4. android fragment 退出程序,android – 应用程序在Fragment中单击后退按钮后关闭
  5. 字符串加括号问题(矩阵乘法组合问题)C++
  6. 页面置换算法(FIFO , LRU, OPT)(C++实现模拟)
  7. pyqt5入门教程(四)
  8. 不是同一个工程的exe与dll,如何调试dll
  9. MyBatis使用动态代理报 invalid bound statement (not found) 错
  10. 8天学通MongoDB——第五天 主从复制