了解继承前我们需要了解函数的构造,方便我们理解。

常见六种继承方式:
1.原型继承call和apply;
2.原型拷贝:循环父函数protype的key值=子函数prototype的key值;
3.原型链继承:父函数实例继承给子函数prototype;
4.混合继承:父函数的protype=子函数的-proto-;
5.寄生继承:新建fn函数,其protype等于父函数protype实例,在将fn的实例等于子函数protype,加consuctor;
6.class类继承:consuctor的super方法;

一、call(),apply():


一般情况下 我们只会用call和apply实现属性的继承 不会实现方法的继承;
prototype:每一个函数都有一个prototyp属性 这个属性指向一个对象 这个对象叫做原型对象
原型对象里面有2个属性:constructor,__proto__   
 原型链:由__proto__组成的链条叫做原型链

一、它们各自的定义:

1.apply:
调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
2.call:
调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
二、它们的共同之处:

都以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。

三、它们的不同之处:
apply:最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个
数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将
导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法
被传递任何参数。
call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法
相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数,
那么 Global 对象被用作thisObj。 实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。*/
/*apply()方法*/
function.apply(thisObj[, argArray]);
/*call()方法*/
function.call(thisObj[, arg1[, arg2[, [, ...argN]]]]);
举例:

/*父类*/
function Parent(add, net, no, teacher) {
this.add = add;
this.net = net;
this.no = no;
this.teacher = teacher
}
/*子类*/
function Child(name, age, sex, id) {
this.name = name;
this.sex = sex;
this.age = age;
this.id = id;
Parent.call(this, "山东", "www.baidu.com", "1608", "ccy"); //这个时候的Parent中的this已经被Child
所代替
}
var child = new Child("fangMing", "18", "男", "10086");
console.log(child.add)
/*如果想用apply方法,可以将注释的一句改为Parent.apply(this,["山东","www.baidu.com","1608","ccy"]),
两者的用法是一样的等效,唯一的区别就是call后面跟的是有个一个一个单独的数据,而apply需要把数据放在数组里面*/

二、原型拷贝:

function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.sleep = function () { }
Person.prototype.play = function () { }
Person.prototype.eat = function () {
console.log("1122")
}
var p1 = new Person()
function Man(beard, larynx, name, age, sex) {
Person.apply(this, [name, age, sex])
this.beard = beard;
this.larynx = larynx;
}
for (var key in Person.prototype) {
Man.prototype[key] = Person.prototype[key]
}
Man.prototype.work = function () { }
Man.prototype.eat = function () {
console.log('3344')
}
//实例化
, "很大", "陈亮", "40", "男");
console.log(chenliang)
console.log([Person])
chenliang.eat()
p1.eat();

三、原型链继承:

/*
原型链继承:实例化父函数,将其
实例

拷贝给子元素的prototype,这样就子函数继承了

了父函数中的方法了。
*/
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.sleep = function () { }
Person.prototype.play = function () { }
Person.prototype.eat = function () {
console.log("1122")
}
var p1 = new Person()
function Man(beard, larynx, name, age, sex) {
Person.apply(this, [name, age, sex])
this.beard = beard;
this.larynx = larynx;
}
/*
1、多了很多无用的属性---->直接使用原型链继承的时候可能把属性和方法都继承过来了
用原型链继承的时候可能把属性放在了prototype上面
2、少了一个constructor
*/
Man.prototype = new Person();
Man.prototype.work = function () { }
//实例化
, "很大", "陈亮", "40", "男");
console.log(chenliang)
console.log(p1)

四、混合继承:

/*
混合继承:将父函数的prototype拷贝给子函数的_proto_
*/
//人类
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.sleep = function () { }
Person.prototype.play = function () { }
Person.prototype.eat = function () {
console.log("1122")
}
var p1 = new Person()
//p1.__proto__:原型对象 == Person.prototype 原型对象
function Man(beard, larynx, name, age, sex) {
Person.apply(this, [name, age, sex])
this.beard = beard;
this.larynx = larynx;
}
/*
1、多了很多无用的属性
2、少了一个constructor
*/
Man.prototype = {
constructor: Man,
__proto__: Person.prototype
}
Man.prototype.work = function () { }
//实例化
, "很大", "陈亮", "40", "男");
console.log(chenliang)
console.log(p1)

>五、寄生继承

/*
寄生继承:创建一个空fn函数,将父函数的prototype拷贝给fn.prototype;
然后将子函数的prototype拷贝fn函数的实例,给子函数加一个constructor指向子函数;
*/
//人类
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.sleep = function () { }
Person.prototype.play = function () { }
Person.prototype.eat = function () {
console.log("1122")
}
var p1 = new Person()
function Man(beard, larynx, name, age, sex) {
Person.apply(this, [name, age, sex])
this.beard = beard;
this.larynx = larynx;
}
/*
1、多了很多无用的属性
2、少了一个constructor
*/
function fn() { }
fn.prototype = Person.prototype;
//原型链继承
Man.prototype = new fn();
Man.prototype.constructor = Man;
Man.prototype.work = function () { }
//实例化
, "很大", "陈亮", "40", "男");
console.log(chenliang)
console.log(p1)

>六、Class类继承

class Person{
//属性
constructor(name,age){
this.name = name;
this.age = age;
}
eat(){
console.log('111')
}
show(){
console.log('222')
}
}
//ES6的继承
class Man extends Person{
constructor(beard,name,age){
super(name,age)
this.beard = beard;
}
work(){}
}
,);
console.log(p2)

深入浅出:了解JavaScript的六种继承的更多相关文章

  1. JavaScript的六种继承方式

    继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的 原型链 首先得要明白什么是原型链,在一篇文章看懂proto和prototype ...

  2. JavaScript 常见的六种继承方式

    JavaScript 常见的六种继承方式 前言 面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分 ...

  3. JavaScript 六种继承方式

    title: JS的六种继承方式 date: 2017-06-27 05:55:49 tags: JS categories: 学习 --- 继承是面向对象编程中又一非常重要的概念,JavaScrip ...

  4. JavaScript常见的六种继承方式

    前言 面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过"类 ...

  5. JavaScript常用,继承,原生JavaScript实现classList

    原文链接:http://caibaojian.com/8-javascript-attention.html 基于 Class 的组件最佳实践(Class Based Components) 基于 C ...

  6. 浅谈 JavaScript 中的继承模式

    最近在读一本设计模式的书,书中的开头部分就讲了一下 JavaScript 中的继承,阅读之后写下了这篇博客作为笔记.毕竟好记性不如烂笔头. JavaScript 是一门面向对象的语言,但是 ES6 之 ...

  7. javascript 之 prototype继承机制

    理解Javascript语言的继承机制 javascript没有"子类"和"父类"的概念,也没有"类"(class)和"实例&qu ...

  8. JavaScript寄生组合式继承分析

    JavaScript寄生组合式继承特点: 避免了在子类prototype上创建不必要多余的属性,相比直接继承基类的实例效率要高. 是JavaScript 实现继承的最有效方式. <script& ...

  9. 深入理解:JavaScript原型与继承

    深入理解:JavaScript原型与继承 看过不少书籍,不少文章,对于原型与继承的说明基本上让人不明觉厉,特别是对于习惯了面向对象编程的人来说更难理解,这里我就给大家说说我的理解. 首先JavaScr ...

随机推荐

  1. 安居客scrapy房产信息爬取到数据可视化(上)-scrapy爬虫

    出发点 想做一个地图热力图,发现安居客房产数据有我要的特性.emmm,那就尝试一次好了~ 老规矩,从爬虫,从拿到数据开始... scrapy的配置 创建一个项目(在命令行下敲~): scrapy st ...

  2. WPF 使用 fontawesome

    <Style TargetType="TextBlock" x:Key="tree-icon"> <Style.Setters> < ...

  3. js获取文件MD5值

    原文链接:http://www.jianshu.com/p/940a9226fbbd   要在web页面中计算文件的md5值,还好这个项目是只需兼容现代浏览器的,不然要坑死了. 其实对文件进行md5, ...

  4. oracle 容灾库日常维护 ,健康检查脚本 以及常见问题分析

    select DEST_ID, APPLIED_SCN FROM v$archive_dest select * from v$dataguard_status; SELECT gvi.thread# ...

  5. 033 Search in Rotated Sorted Array 搜索旋转排序数组

    假设按照升序排序的数组在预先未知的某个关键点上旋转.(即 0 1 2 4 5 6 7 将变成 4 5 6 7 0 1 2).给你一个目标值来搜索,如果数组中存在这个数则返回它的索引,否则返回 -1.你 ...

  6. 关于Function.prototype.apply.call的一些补充

    宿主对象,在javascript中有三类对象,本地对象,内置对象和宿主对象.其他两类暂且不提,宿主对象是指什么呢(DOM BOM),控制台对象是文档对象模型的扩展,也被认为是宿主对象.那么,它们有什么 ...

  7. Hadoop实战:明星搜索指数统计,找出人气王

    项目介绍 本项目我们使用明星搜索指数数据,分别统计出搜索指数最高的男明星和女明星. 数据集 明星搜索指数数据集,如下图所示.猛戳此链接下载数据集 思路分析 基于项目的需求,我们通过以下几步完成: 1. ...

  8. HDU 5465——Clarke and puzzle——————【树状数组BIT维护前缀和+Nim博弈】

    Clarke and puzzle Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  9. 使用原生javascript实现瀑布流

    简介 瀑布流布局是一种很常见的布局方式,他的主要视觉体验为图片元素等宽不等高,图片元素之间的水平排序参差不齐,而且随着滚动条的滚动,数据会进行异步的加载,这样的布局有两个好处,1-有视觉的冲击力,比较 ...

  10. IoC和AOP使用扩展。。。

    实现依赖的多种方式. 1.理解构造注入. 2.掌握使用p命名空间实现属性注入. 3.理解不同的数据类型的注入方式. 4.如何通过构造注入为业务类注入所依赖的数据访问层对象,实现保存用户数据功能. 5. ...