原型

我们知道任何一个函数都存在一个prototype属性,他是个对象,这个对象 我们就叫他原型对象
这个原型对象本身也自带两个属性:constructor 和 proto

constructor: 这个属性是指向创建此对象的构造函数的引用,构造函数的实例化对象,也可以通过constuctor属性来访问构造它的那个函数

_proto_: 这个属性指向创建此对象的构造函数的prototype原型对象的引用

  例子:
//我的家族姓莫
function Parent(){this.name = 'mo'
}
//我家族是音乐世家Parent.prototype.work = function(){return 'musicing'}//爸妈生了我var me = new Parent()//我也要唱歌console.log(me.work())   //=>musicing//爸爸妈妈又生了二胎var myBrother = new Parent()//他也会唱歌console.log(myBrother.work())  //=>musicing//证明我两是否是亲生的console.log(me.work() === myBrother.work())  //=>true解释一波:me 和 myBrother 是构造函数Parent()new出来的的一个实例,me 和 myBrother 都有一个隐式属性_proto_,引用Parent() 的prototype属性来得到继承

原型链

在访问 me 的 work 方法时,找不到, 就会顺着_protp_属性往上在构造函数的prototype找,找到了就停止,没找到继续往上到Object.prototype找,再没找到就到null了,自然也找不到就只能返回undifined,这种链式的引用就是原型链,通过原型链实现继承还是很方便的

万一原型链断链呢?

原因:如果对 构造函数 或者 原型链 修改一些方法或者属性的时候,导致函数的constructor不等于创建它的构造函数,那就会断链

如果 先实例再通过 字面量添加或修改,那么后新定义的方法就对先继承的方法或属性就会不在生效,就会断链,这是因为字面量来修改原型时,constructor发生了改变,也就是说该函数指向的创建该函数的构造函数发生了改变,字面量默认的constructor的值是Object(),所以为了避免断链,尽量不要使用字面量重新赋值,修改

 例子://创建一个构造函数Car
function Car(){this.brand = '大奔';
}
//大奔 80万
Car.prototype.price = '80';//我来买一个大奔 先实例
var benCar1 = new Car();
console.log(benCar1.price)  //=>80//我希望我的大奔 带有翅膀的 能飞
Car.prototype = {hasWing: true,hasFlying: function(){console.log('flying...')}
}var benCar = new Car()(1) 正常情况下
console.log(benCar1.brand,benCar1.price,benCar1.hasWing,benCar1.hasFlying,benCar1.constructor)//=> 大奔 80 undefined undefined  ƒ Car(){}(2)字面量添加属性方法时
console.log(benCar.brand,benCar.price,benCar.hasWing,benCar.hasFlying,benCar.constructor)
//=> 大奔 undefined true ƒ (){} ƒ Object() { [native code] }

继承的几种方式

(1) 原型链继承

原型链继承是通过 new实例化构造函数 赋给子类的原型, 其实实例的子类本身是完全的空对象,所有的属性方法都需要去原型链上找。

例子:function Grandpa(){this.name = 'mo'
}
Grandpa.prototype.work = function(){return 'musicing'}function Parent(){}
Parent.prototype = new Grandpa()var me = new Parent()console.log(me.work())   //=>musicing 我找啊找啊原来是Grandpa会musicingvar myBrother = new Parent()console.log(myBrother.work())  //=>musicingconsole.log(me.work() === myBrother.work())  //=>true

(2) 构造函数继承

构造函数继承 通过apply去调用父类的构造函数,达到继承父类的实例属性,对,只能继承属性,要想继承方法 采用寄生组合继承

例子
function Grandpa(firstname){this.name = 'mo ' + firstname
}
Grandpa.prototype.work = function(){return 'musicing'}function Parent(firstname){Grandpa.apply(this, arguments)
}
Parent.prototype = new Grandpa()var me = new Parent('alice')console.log(me.work())   //=>musicingvar myBrother = new Parent('bob')console.log(myBrother.work())  //=>musicingconsole.log(me.work() === myBrother.work())  //=>trueconsole.log(me.name, myBrother.name,me.name === myBrother.name)//=>mo alice ,mo bob ,false

(3) 寄生组合继承

寄生组合继承是我们经常要用到的,组合了原型和构造函数,结合Object.create(obj),方法对传入的对象进行浅拷贝,这样可以实现对实例属性和原型属性分别进行继承

浅拷贝:仅仅是指向被拷贝的内存地址,如果原地址中对象被改变了,那么浅拷贝出来的对象也会相应改变

例子:
// 寄生组合继承
function Grandpa(firstname){this.name = 'mo ' + firstname
}
Grandpa.prototype.work = function(){return 'musicing'}function Parent(firstname){Grandpa.apply(this, arguments)
}
// Parent.prototype = new Grandpa()
//改成
Parent.prototype = Object.create(Grandpa.prototype); // Object.create()将父级对象的属性和方法进行引用
Parent.prototype.constructor = Parent;  //将该函数的construnctor指向parent构造函数
console.log(Parent.prototype)var me = new Parent('alice')var myBrother = new Parent('bob')console.log(me.work() === myBrother.work())  //=>true
console.log(me.name, myBrother.name,me.name === myBrother.name)//=>mo alice ,mo bob ,false

好了,有时间还会补充...

经典原型链、继承解析相关推荐

  1. JavaScript: 原型链继承(原理解析 + 代码实现 + 结构图解)

    文章目录 一 原型搜索机制 1.1 代码实现 1.2 结构图解 1.3 搜索机制 二 原型链代码实现 2.1 代码实现 2.2 结构图解 2.3 链条拓展 三 原型链的缺点 原型链是实现继承的一种方式 ...

  2. JavaScript进阶学习(二)—— 基于原型链继承的js工具库的实现方法

    文章来源:小青年原创 发布时间:2016-07-03 关键词:JavaScript,原型链,jQuery类库 转载需标注本文原始地址: http://zhaomenghuan.github.io... ...

  3. Javascript 对象继承 原型链继承 对象冒充 call 混合方式

    一.原型链继承 function ClassA() {} ClassA.prototype.color = "blue"; ClassA.prototype.sayColor = ...

  4. 记录--JS精粹,原型链继承和构造函数继承的 “毛病”

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 先从面向对象讲起,本瓜认为:面向对象编程,它的最大能力就是:复用! 咱常说,面向对象三大特点,封装.继承.多态. 这三个特点,以" ...

  5. ES6 继承(复习原型链继承)

    2019独角兽企业重金招聘Python工程师标准>>> 原型链继承 <script type="text/javascript">/* 原型链 继承 ...

  6. JavaScript_原型链继承

    1.原型链继承 <script type="text/javascript">function Supper() {this.supProp = "Suppe ...

  7. 一个贴近实际的原型链继承的列子

    自从四月份换工作后,一方面要适应新的环境,另一方面也是自己的惰性作怪,已经好长时间没写博客了,整个人都松懈了下来:刚好最近工作不忙,新环境也适应好了,感觉还是得给自己充充电,趁着业余时间多学点东西,顺 ...

  8. JavaScript简餐——继承之原型链继承

    文章目录 前言 一.实现方式 二.继承实例 三.问题所在 1.引用值误修改 2.子类型实例化时无法给父类构造函数传参 四.总结 前言 写本<JavaScript简餐>系列文章的目的是记录在 ...

  9. 继承方式之原型链继承

    继承方式之原型链继承: 今天实践了一下原型链继承,与之前也是有了更深一点的理解和体会吧.顺便写点东西,加深一下印象,有哪里说得不对的,请大家评论留言,本人一定洗耳恭听,虚心学习. 原型链继承,顾名思义 ...

  10. 原型链继承和构造函数继承

    //原型链继承function Father(name,age){//构造器this.name=name;this.age=age;this.say=function(){console.log(th ...

最新文章

  1. 微服务限流Sentinel讲解(一)
  2. muduo之Atomic
  3. method-dispatch/
  4. 【Android面试】Android面试题集锦 (陆续更新)
  5. 【渝粤教育】 国家开放大学2020年春季 1444药理学(本) 参考试题
  6. [李景山php]每天TP5-20161225|thinkphp5-Console.php-2
  7. Slickflow.NET核心开源工作流引擎
  8. centos编译安装python_CentOS编译安装Python3
  9. Python3爬虫(六) 解析库的使用之Beautiful Soup
  10. linux挂载sata硬盘分区,Linux下挂载硬盘分区的几种方法
  11. 存储和多屏互动,蜂鸟网的NAS应用解析
  12. 原生JS制作自动+手动轮播图,附带二级分类菜单
  13. 网络(十三)之ACL的高级应用
  14. 迅雷API批量下载巨潮年报
  15. 猎豹wifi有linux,电脑无线网卡过旧无法安装猎豹免费wifi的解决方法
  16. 计算机管理事件id10016,事件 ID 10016 已记录Windows - Windows Client | Microsoft Docs
  17. android 图片轮播带缩略图,超酷响应式带缩略图的jQuery轮播图插件
  18. 基于ssm的社团报名管理系统开题答辩问题
  19. python中的根号_python怎么表示根号运算
  20. android NE 分析

热门文章

  1. Atitit web 之道 艾龙著 Atitit web 之道 艾龙艾提拉著v2 saa.docx 1. 第1章 Web编程基础知识 (1) 3 1.1. 1.1 什么是Web (1) 3 1.2.
  2. Atitit 互联网行业如何提升收入 经济学概论读后感 attilax总结 1. 收入“四 位一体”的理论(工资、利润、利息、地租) 1 2. 提升收入,就要提升这4个象限的收入 1 3. 如
  3. Atitit 视图状态ViewState)的原理与管理
  4. 投行巨头金融科技战略——摩根士丹利财富管理转型之路篇
  5. android 视频录制 sdk,android视频录制实现方法
  6. 【优化算法】混合增强灰狼优化布谷鸟搜索算法(AGWOCS)【含Matlab源码 1331期】
  7. 【TWVRP】基于matlab粒子群算法求解带时间窗的车辆路径规划问题【含Matlab源码 334期】
  8. python用缩进来写模块_进击python第一篇:相遇
  9. c++ 取整_MPIP Raw转Raw图简述-C实现
  10. springcloudalibaba 架构图_Spring Cloud Alibaba 架构实战