JavaScript面向对象

继承extend

1. 概念(主要用途)

将子类中的共性代码 ( 属性和方法 ) 抽取出来 放到父类中 每当有一个新的子类需要用到共性的属性或者方法时 不需要在自己内容复写一遍 只需要继承父类的代码


2. 继承的优点与缺点

2.1 优点

  • 实现代码复用 共性代码不需要重写 只需要继承父类即可

  • 提高了代码可维护性 (同时也是缺点) 父类中共性代码改变 子类跟随改变 子类也可以在自己的类中重写共性代码完成自己需求

  • 继承是多态的前提条件 它使得类与类之间产生了联系


2.2 缺点

  • 违反了开发原则(高内聚 低耦合) 类的耦合性增高了

  • 耦合: 类与类之间的联系

  • 内聚: 类独自完成某件事的能力


3. JS继承的方式

注意: 理解new和this是理解继承的前提

3.1 构造函数继承

使用call方法改变父类中的this指向到子类上

function Fn(name1) {
this.name = name1;
} function FnSon(name2) {
Fn.call(this, name2);
//如果子类中有父类同名属性应写在call下面
} const fs = new FnSon('bob');
console.log(fs);
// FnSon {name: 'bob'}

特点

  • 写法简易

  • 易于做多继承

  • 只能继承构造函数内的属性和方法 无法继承构造函数原型上面的属性和方法


3.2 原型对象继承

将父类原型Prototype深拷贝给子类原型Prototype

  // 创建父类构造函数
function Parent(n){
this.name = n;
}
Parent.prototype.show = function(){
console.log(this.name);
} // 创建子类构造函数
function Child() {} //将父类Prototype内容深拷贝给子类Prototype
Child.prototype = {
...Parent.prototype,
constructor: Child
//用这种方法继承会缺失constructor 要自己指明
} Child.prototype.show = function() {
console.log('hello');
} // 重写父类中的show方法

特点

  • 只能继承父类构造函数原型上属性和方法 不能继承构造函数内的属性和方法

  • 可以实现多继承


3.3 原型链继承

将子类构造函数的Prototype指向父类实例对象的__proto__

  function Parent(n){
this.name = n
}
Parent.prototype.show = function(){
console.log(this.name)
} function Child() {} // 将父类的实例对象的__proto__给子类的原型
// 如果父类有参数要传 必须在原型链继承时候就给上实参(不实用)
Child.prototype = new Parent('hello show'); // 在继承之前:子类构造函数的Prototype 指向 子类构造函数的Prototype
// 完成继承之后:子类构造函数的Prototype 指向 父类实例对象的__proto__ 指向 父类构造函数的Prototype

注意: 如果把子类构造函数的Prototype直接指向父类构造函数的Prototype(浅拷贝) 那子类重写父类方法的时 父类跟随一起改变

特点

  • 既能继承构造函数内的属性和方法,又能继承原型上的属性和方法

  • 因为在继承时候就要处理参数 所以不实用

  • 不适合多继承 (原型链多继承需要用B继承A 再用C继承B 这样就可以达到多继承(C继承A和B)目的 但是会增加原型链层级)


3.4 组合(混合)继承

构造继承 + 原型继承/原型链继承

这种方法结合了单个方法的优点

 // 构造继承 + 原型继承
function Parent(n){
this.name = n
}
Parent.prototype.show = function(){
console.log(this.name)
} function Child(n){
// 用构造继承继承父类构造函数中属性和方法
// 弥补原型继承无法继承构造函数中属性和方法的缺点
Parent.call(this, n);
}
// 用原型继承能继承父类原型中属性和方法优势
// 弥补构造继承无法继承父类原型中属性和方法的缺点
Child.prototype = {
...Parent.prototype,
constructor: Child
//依旧缺少constructor 要自己指明
//constructor 是用来标记当前Prototype所属函数
}
 // 构造继承 + 原型链继承

  function Parent(n){
this.name = n
}
Parent.prototype.show = function(){
console.log(this.name)
} // 用构造继承弥补了原型链继承必须在继承时就传参的缺点
function Child(n){
Parent.call(this, n);
}
// 用原型链继承能继承父类原型中属性和方法优势
// 弥补构造继承无法继承父类原型中属性和方法的缺点
Child.prototype = new Parent();
Child.prototype.constructor = Child;
//缺少constructor 要自己指明
//constructor 是用来标记当前Prototype所属函数

3.5 ES6新增extends继承

使用extends关键字和super(形参)来达到继承

  // ES6创建构造函数
class Parent{
constructor(name, age){
this.name = name;
this.age = age;
}
show(){
console.log(this.name)
}
}
// ES6extends关键字
class Child extends Parent{
constructor(n, a){
// 父类又称超类
// super 代表了父类构造函数
// 但是返回的是子类实例
// 即 super 内部的 this 指的是子类实例
// 因此 super(n, a) 在这里相当于 A.prototype.constructor.call(this, n, a)
// n a对应了父类中的name age
super(n, a);
}
// 重写父类中方法
show(){
console.log("重写父类show方法")
}
}

注意

  • 如果不写super会报错 父类中没有形参 super()也不用给 super形参和父类一一对应
  • super只能在有extends的子类class中使用

4. 实例和构造函数关系检测

  • 关键字: instanceof

实例对象 instanceof 构造函数

  function Parent(){}

  function Child(){}

  // Child原型链继承parent
Child.prototype = new Parent(); const p = new Parent(); const c = new Child(); console.log( p instanceof Parent );
// true
console.log( c instanceof Child );
// true
console.log( c instanceof Parent );
// true Child继承Parent
console.log( p instanceof Child );
// false Parent并没有继承Child

  • 原型对象方法: isProtoypeOf()

构造函数.prototype.isPrototypeOf(实例对象)

  function Parent(){}

  function Child(){}

  // Child原型链继承parent
Child.prototype = new Parent(); const p = new Parent(); const c = new Child(); console.log( Parent.prototype.isPrototypeOf( p ) );
// true
console.log( Child.prototype.isPrototypeOf( c ) );
// true
console.log( Parent.prototype.isPrototypeOf( c ) );
// true Child继承Parent
console.log( Child.prototype.isPrototypeOf( p ) );
// false Parent并没有继承Child

只要实例对象和构造函数存在关系 无论中间隔多少层都 返回true 否则返回false

可以利用这两种方法区分对象 数组 Set Map等

  let arr = [];
let obj = {}; console.log(arr instanceof Array)
// true
console.log(Array.prototype.isPrototypeOf(arr))
// true
console.log(pbj instanceof Array)
// false
console.log(Array.prototype.isPrototypeOf(obj))
// false
  • 万能检测方法

Object.prototype.toString.call()

 Object.prototype.toString.call("hello")
// [object String]

注意

用instanceof和isPrototypeOf()不能检测undefined和null

这两种数据只能用万能检测法

extend笔记的更多相关文章

  1. jQuery学习笔记之extend方法小结

    在学习jQuery的时候,学习到了$.extend的主要用法,在此做一个简单的总结. (1)当只写一个对象自变量时,拓展的是jQuery的工具方法,如: $.extend({ aaa:function ...

  2. jquery中方法扩展 ($.fn & $.extend) 学习笔记

    A.$.fn 1.$.fn.method() 函数为jQuery对象扩展一个属性和方法(主要用于扩展方法) :method 为自定义方法名 ($.fn 等效 $.prototype) $.fn.bor ...

  3. jQuery笔记之工具方法extend插件扩展

    jQuery工具方法 $.extend()插件扩展(工具方法) $.fn.extend()插件扩展(实例方法) 浅度克隆.深度克隆 两个方法基本是一样的,唯一不同的就是调用方式不一样 -------- ...

  4. Sass学习笔记之入门篇

    Sass又名SCSS,是CSS预处理器之一,,它能用来清晰地.结构化地描述文件样式,有着比普通 CSS 更加强大的功能. Sass 能够提供更简洁.更优雅的语法,同时提供多种功能来创建可维护和管理的样 ...

  5. javascript继承笔记

    //原型(prototype):原型是一个对象,其他对象可以通过它实现属性继承 /*笔记: * 1.类式继承:通过原型链继承的方式 * 2.原型式继承:对类式继承的封装 * 3.寄生式继承:对原型继承 ...

  6. 机器学习实战笔记(Python实现)-03-朴素贝叶斯

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  7. 机器学习实战笔记(Python实现)-02-决策树

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  8. jQuery 学习笔记

    jQuery 学习笔记   一.jQuery概述    宗旨: Write Less, Do More.    基础知识:        1.符号$代替document.getElementById( ...

  9. 初学者的python学习笔记2

    本来想是先把作业二搞定的,结果发现作业二用的字典,一脸懵逼,还是先搞定第二课吧.其实第二课和第一课内容差不多,据说是第一课的老师去美国了……不管怎么样先整理一下吧. ----------------- ...

  10. 初学者的python学习笔记1

    推荐一段时间闲的蛋疼,总觉得再堕落下去不太好,便捡起了之前一直想学而没有学的python,以此记录一下学习笔记,同时亦是督促和复习. 学习51cto上的<2016最新Python开发基础课程-2 ...

随机推荐

  1. 【原创】windows环境下Java串口编程

    由于工作中遇到需要读取SBG Ellipse N系列的惯导模块数据,为了方便操作,我选择在Windows下进行串口开发.串口使用RS232. Ellipse-N RS232的引脚定义 开始我尝试使用的 ...

  2. 实验二 K-近邻算法及应用

    博客班级 https://edu.cnblogs.com/campus/ahgc/machinelearning 作业要求 https://edu.cnblogs.com/campus/ahgc/ma ...

  3. Conda 创建、激活、克隆、删除虚拟环境 - 搬运

    Conda 创建.激活.克隆.删除虚拟环境 转自 :https://zhuanlan.zhihu.com/p/547724114 风影忍着   通常来说,对于每一个新的项目,我们都需要创建一个新的环境 ...

  4. tableau连接mysql

    1.下载驱动地址:https://dev.mysql.com/downloads/connector/odbc/ 2.选择MSI Installer自动安装自动配置 3.本地127.0.0.1(其他I ...

  5. [BUUCTF]HCTF 2018WarmUp1 write up

    ctrl+U查看源代码, 如下: 访问提示中的source.php文件 发现显示了源码,且存在另一个PHP文件hint.php(提示.php),先查看文件内是否有信息 用file来传参,并且要绕过wh ...

  6. JDK 7 HashMap 并发情况下的死锁问题

    目录 问题描述 详细解释 问题描述 JDK7的 HashMap 解决冲突用的是链表,在插入链表的时候用的是头插法,每次在链表的头部插入新元素.resize() 的时候用的依然是头插,头插的话,如果某个 ...

  7. python内置函数range()—对象创建函数

    range()函数 介绍 range()函数实际上表示一个不可变的数字序列类型,通常用于在for循环中指定特定的次数. range()的格式: range(stop) range(start, sto ...

  8. SHELL-反弹shell

    什么是shell? 在我们深入了解发送和接收 shell 的复杂性之前,了解 shell 实际上是什么很重要.用最简单的术语来说,shell 就是我们在与命令行环境 (CLI) 交互时使用的工具.换句 ...

  9. 文件上传靶场 upload-labs Pass 5-10

    Pass-5 .user.ini文件 根据我的观察,最新版的upload-labs第五关和旧版的不一样,这一关可以使用和Pass-10一样的方法通过,但是,其他所有的关卡都禁止了.ini文件的上传,就 ...

  10. git clone的时候出现 fatal: unable to access 'https://github.com/...':OpenSSL SSL_read: Connection was reset, errno 10054解决方法

    git clone的时候出现fatal: unable to access 'https://github.com/...':OpenSSL SSL_read: Connection was rese ...