原文链接:https://blog.csdn.net/u012468376/article/details/53127929

一、继承的概念

​ 继承是所有的面向对象的语言最重要的特征之一。大部分的oop语言的都支持两种继承:接口继承和实现继承。比如基于类的编程语言Java,对这两种继承都支持。从接口继承抽象方法 (只有方法签名),从类中继承实例方法。

​ 但是对JavaScript来说,没有类和接口的概念(ES6之前),所以只支持实现继承,而且继承在 原型链 的基础上实现的。等了解过原型链的概念之后,你会发现继承其实是发生在对象与对象之间。这是与其他编程语言很大的不同。

二、原型链的概念

在JavaScript中,将原型链实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法

​ 再回顾下,构造函数、原型(对象)和对象之间的关系。每个构造函数都有一个属性 prototype 指向一个原型对象,每个原型对象也有一个属性 constructor 指向函数,通过new 构造函数() 创建出来的对象内部有一个不可见的属性[[prototype]]指向构造函数的原型。当每次访问对象的属性和方法的时候,总是先从p1中找,找不到则再去p1指向的原型中找。

2.1 更换构造函数的原型

原型其实就是一个对象,只是默认情况下原型对象是浏览器会自动帮我们创建的,而且自动让构造函数的 prototype 属性指向这个自动创建的原型对象。

​ 其实我们完全可以把原型对象更换成一个我们自定义类型的对象。

看下面的代码:

说明:

1、定义Son构造函数后,我们没有再使用Son的默认原型,而是把他的默认原型更换成了Father类型对象。
 2、这时,如果这样访问 son1.name, 则先在son1中查找name属性,没有然后去他的原型( Father对象)中找到了,所以是"马云"。
 3、如果这样访问 son1.giveMoney(), 则现在son1中这个方法,找不到去他的原型中找,仍然找不到,则再去这个原型的原型中去找,然后在Father的原型对象找到了。
 4、从图中可以看出来,在访问属性和方法的时候,查找的顺序是这样的:对象->原型->原型的原型->…->原型链的顶端。 就像一个链条一样,这样由原型连成的"链条",就是我们经常所说的原型链。
 5、从上面的分析可以看出,通过原型链的形式就完成了JavaScript的继承。

2.2 默认顶端原型

其实上面原型链还缺少一环。

​ 在 JavaScript 中所有的类型如果没有指明继承某个类型,则默认是继承的 Object 类型。这种 默认继承也是通过原型链的方式完成的。

下面的图就是一个完整的原型链:

说明:

1、原型链的顶端一定是Object的原型对象。这也是为什么我们随意创建一个对象,就有很多方法可以调用,其实这些方法都是来自Object的原型对象。
 2、通过对象访问属性方法的时候,一定是会通过原型链来查找的,直到原型链的顶端。
 3、一旦有了继承,就会出现多态的情况。假设需要一个Father类型的数据,那么你给一个Father对象,或Son对象都是没有任何问题的。而在实际执行的过程中,一个方法的 具体执行结果,就看在原型链中的查找过程了。给一个实际的Father对象则从Fahter的原型链中查找,给一个实际的Son则从Son的原型链中查找。
 4、因为继承的存在,Son的对象,也可以看出Father类型的对象和Object类型的对象。 子类型对象可以看出一个特殊的父类型对象。

2.3 测试数据的类型

到目前为止,我们有3中方法来测试数据的类型。

  1. **typeof:**一般用来测试简单数据类型和函数的类型。如果用来测试对象,则会一直返回object,没有太大意义。

3.1 借用的方式

借用构造函数调用继承,又叫伪装调用继承或冒充调用继承。虽然有了继承两个子,但是这种方法从本质上并没实现继承,只是完成了构造方法的调用而已。

​ 使用call或apply这两个方法完成函数借调。这两个方法的功能是一样的,只有少许的区别(暂且不管)。功能都是更改一个构造方法内部的this指向到指定的对象上。

看下面的代码:

四、组合继承

组合函数利用了原型继承和构造函数借调继承的优点,组合在一起。成为了使用最广泛的一种继承方式。

1、组合继承是我们实际使用中最常用的一种继承方式。
 2、可能有个地方有些人会有疑问:Son.prototype = new Father( );这不照样把父类型的属性给放在子类型的原型中了吗,还是会有共享问题呀。但是不要忘记了,我们在子类型的构造函数中借调了父类型的构造函数,也就是说,子类型的原型中有的属性,都会被子类对象中的属性给覆盖掉。就是这样的。

【转】js原型链与继承的更多相关文章

  1. js原型链与继承(初体验)

    js原型链与继承是js中的重点,所以我们通过以下三个例子来进行详细的讲解. 首先定义一个对象obj,该对象的原型为obj._proto_,我们可以用ES5中的getPrototypeOf这一方法来查询 ...

  2. 深入理解JS原型链与继承

    我 觉得阅读精彩的文章是提升自己最快的方法,而且我发现人在不同阶段看待同样的东西都会有不同的收获,有一天你看到一本好书或者好的文章,请记得收藏起来, 隔断时间再去看看,我想应该会有很大的收获.其实今天 ...

  3. JS原型链与继承别再被问倒了

    原文:详解JS原型链与继承 摘自JavaScript高级程序设计: 继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实 ...

  4. js 原型链和继承(转)

    在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的 new 到底是干什么的 1. 什么是 JS 原型链? 我们知道 JS 有对象,比如 var ob ...

  5. 小谈js原型链和继承

    原型(prototype)在js中可是担当着举足轻重的作用,原型的实现则是在原型链的基础上,理解原型链的原理后,对原型的使用会更加自如,也能体会到js语言的魅力. 本文章会涉及的内容 原型及原型对象 ...

  6. js原型链和继承

    在了解js原型链之前构造函数.原型对象.对象实例这几种概念必须要明白. 1. 创建对象有几种方法 //原型链指向objectvar o1={name:'o1'}; var o11=new Object ...

  7. js 原型链与继承

    var A = function(){ this.name="xiaoming"; } A.prototype.age=9; var a = new A(); console.lo ...

  8. js原型链、继承、this指向等老生常谈却依然不熟的知识点——记录解析

    开始记录学习过程—— 很详细的解析过程——https://juejin.im/post/5c72a1766fb9a049ea3993e6 借鉴阅读——https://github.com/KieSun ...

  9. js原型链+继承 浅析

    名称:    prototype--原型对象    __proto__--属性 原型链与继承网上搜索定义,看起来挺绕的 .先说继承: 所有的对象实例都可以共享原型对象包含的属性和方法  例如一个实例A ...

随机推荐

  1. [go]template使用

    //index.html {{if gt .Age 18}} <p>hello, old man, {{.Name}}</p> {{else}} <p>hello, ...

  2. SQL-W3School-高级:SQL JOIN

    ylbtech-SQL-W3School-高级:SQL JOIN 1.返回顶部 1. SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据. Join 和 Key 有时为了得到完 ...

  3. Hibernate fetch相关

    fetch=FetchType.LAZY 时,spring boot jackson 返回数据时会出错. 可配置使用Hibernate4Module 帮助解决: @Configurationpubli ...

  4. [Scikit-learn] 1.5 Generalized Linear Models - SGD for Classification

    NB: 因为softmax,NN看上去是分类,其实是拟合(回归),拟合最大似然. 多分类参见:[Scikit-learn] 1.1 Generalized Linear Models - Logist ...

  5. Spring Aop(十二)——编程式的创建Aop代理之AspectjProxyFactory

    转发地址:https://www.iteye.com/blog/elim-2397922 编程式的创建Aop代理之AspectjProxyFactory 之前已经介绍了一款编程式的创建Aop代理的工厂 ...

  6. ThreadingTCPServer源码解析

    实例 #!/usr/bin/env python #-*- coding:utf-8 -*- import SocketServer class Myserver(SocketServer.BaseR ...

  7. java面试考点-HashTable/HashMap/ConcurrentHashMap

    HashTable 内部数据结构是数组+链表,键值对不允许为null,线程安全,但是锁是整表锁,性能较差/效率低 HashMap 结构同HashTable,键值对允许为null,线程不安全, 默认初始 ...

  8. elasticsearch启动日志报错not enough master nodes discovered during pinging (found [[]], but needed [-1]), pinging again

    排查步骤 逻辑上讲是,一个节点去ping  master节点,结果却没有得到回应,多次重试依旧失败.应该重点观察: 1.master启动后,IP是否可以有防火墙权限,设置防火墙规则或则直接关闭防火墙 ...

  9. vue项目中兼容ie8以上浏览器的配置

    1.首先需要在根目录的index.html文件加入如下代码 <meta http-equiv="X-UA-Compatible" content="IE=edge& ...

  10. 【ARM-Linux开发】【Qt开发】Qt Creator自定义编译运行步骤

    原文:http://www.linuxidc.com/Linux/2015-04/115763.htm 一直用Qt Creator开发.无它,只是因为linux下C++ IDE选择不多.同时因为我抛弃 ...