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

常见六种继承方式:
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的六种继承方式
继承是面向对象编程中又一非常重要的概念,JavaScript支持实现继承,不支持接口继承,实现继承主要依靠原型链来实现的 原型链 首先得要明白什么是原型链,在一篇文章看懂proto和prototype ...
- JavaScript 常见的六种继承方式
JavaScript 常见的六种继承方式 前言 面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分 ...
- JavaScript 六种继承方式
title: JS的六种继承方式 date: 2017-06-27 05:55:49 tags: JS categories: 学习 --- 继承是面向对象编程中又一非常重要的概念,JavaScrip ...
- JavaScript常见的六种继承方式
前言 面向对象编程很重要的一个方面,就是对象的继承.A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法.这对于代码的复用是非常有用的. 大部分面向对象的编程语言,都是通过"类 ...
- JavaScript常用,继承,原生JavaScript实现classList
原文链接:http://caibaojian.com/8-javascript-attention.html 基于 Class 的组件最佳实践(Class Based Components) 基于 C ...
- 浅谈 JavaScript 中的继承模式
最近在读一本设计模式的书,书中的开头部分就讲了一下 JavaScript 中的继承,阅读之后写下了这篇博客作为笔记.毕竟好记性不如烂笔头. JavaScript 是一门面向对象的语言,但是 ES6 之 ...
- javascript 之 prototype继承机制
理解Javascript语言的继承机制 javascript没有"子类"和"父类"的概念,也没有"类"(class)和"实例&qu ...
- JavaScript寄生组合式继承分析
JavaScript寄生组合式继承特点: 避免了在子类prototype上创建不必要多余的属性,相比直接继承基类的实例效率要高. 是JavaScript 实现继承的最有效方式. <script& ...
- 深入理解:JavaScript原型与继承
深入理解:JavaScript原型与继承 看过不少书籍,不少文章,对于原型与继承的说明基本上让人不明觉厉,特别是对于习惯了面向对象编程的人来说更难理解,这里我就给大家说说我的理解. 首先JavaScr ...
随机推荐
- Ubuntu14.04下sogou输入法的输入框只显示英文不显示中文的问题
解决方法:首先强制更新,把依赖文件全部安装 sudo apt-get install -f 如果仍然不管用,删除sogou的配置文件,在~/.config目录下,一般情况下是SogouPY.Sogou ...
- 【转】grunt动态生成文件名
动态生成文件名 expand 设置为true打开以下选项 cwd 所有src指定的文件相对于这个属性指定的路径 src 要匹配的路径,相对与cwd dest 生成的目标路径前缀 ext 替换所有生成的 ...
- TortoiseSVN 搭建本地版本库及简单操作使用
TortoiseSVN是windows上一款著名的版本控制软件,对于我们管理自己的代码,特别是对一个团队来说,非常重要. 本文探讨的是如何搭建本地的版本库. (1)安装TortoiseSVN之后需要创 ...
- iOS开发 - 3D Touch 应用系列一 - Quick Actions 创建桌面 Icon 快捷方式
个言 很久没发随笔了,有一年多了吧.期间也曾想继续去写随笔,但是因为各种原因而耽搁了.最近又想了一下,还是有很多东西想要写,想要分享,想要记录下来的东西.之后我也会不断写随笔,但不止于 iOS 的方向 ...
- nodejs加密解密
nodejs是通集成在内核中的crypto模块来完成加密解密. 常用加密解密模块化代码: /** * Created by linli on 2015/8/25. */ var crypto = re ...
- docker exit status 255解决
一 windows开发整docker就是痛苦,在公司win7电脑想拿起几年没再用的docker 结果直接报错 Error getting IP address: ssh command error: ...
- Java学习笔记--类和对象
1.介绍面向对象的编程 面向对象是现在主流的编程样例,它替代了以前C语言使用时的“结构体”,Java是一门面向对象的语言,所以需要熟悉面向对象的概念.面向对象的程序由很多对象组成,每 ...
- 关于wav文件fft处理后x,y轴坐标数据的问题
1.关于横坐标的频率的最大值是采样频率,那么每个点对应的频率值就很好算了:f(n) = [Fs/(N/2)]*n (Fs是采样频率,常见的是44.1KHz(44100),N是采样点数,k表是第k个点 ...
- 1 误删dbf文件造成ORA-01109: 数据库未打开.
1.cmd-sqlplus /nolog-conn system/pwd as sysdba 2.shutdown immediate; 3.startup mount; 4.alter databa ...
- HhashMap HashTable ConcurrentHashMap
hashMap hashTable concurrentHashMap hashMap的效率高于hashTable,hashMap是线程不安全的,并发时hashMap put方法容易引起死循环,导致c ...