继承与多态

  • 引入问题
  • 一、继承
    • 1. 步骤
      • (1) 找到所有子对象共同的父对象
      • (2) 将所有子对象公共的方法定义添加到共同的父对象中
      • (3) 所有子对象因继承关系而直接使用父对象中公共的方法
    • 2. 原型中this的指代
    • 3.自有属性和共有属性
    • 4.内置类型的原型对象:
      • 11种内置类型 (背)
    • 5. 原型链:
  • 二、多态
    • 1.override重写
      • 图解

引入问题

构造函数只能重用代码结构,但是浪费内存。

(1)凡是放在构造函数中的方法定义,每创建一个新对象,都要重复创建这个方法对象的副本!

所以,构造函数中不应该包含方法的定义!

一、继承

(1)定义:父对象的成员,子对象无需重复创建就可直接使用。
既可重用代码, 又可节约内存

(2)何时使用?
只要同一类型多个对象都需要公共的方法定义时,就要用继承实现

1. 步骤

(1) 找到所有子对象共同的父对象

a.定义每个构造函数时都会自带一个原型对象——prototype

b.可通过"构造函数.prototype"属性访问到这个暂时为空的原型对象

c. new的第二步:
让新创建的子对象自动继承构造函数的原型对象
new 会自动设置新子对象:
__proto__=构造函数.prototype
只有从__proto__指出去的关系才是继承

(2) 将所有子对象公共的方法定义添加到共同的父对象中

如何向原型对象中添加新的共有属性和方法:
只能强行赋值:

构造函数.prototype.共有方法=function(){ ... }构造函数.prototype.共有属性=属性值

(3) 所有子对象因继承关系而直接使用父对象中公共的方法

用子对象.访问对象成员时,js引擎先在子对象内部查找自有的属性。
如果子对象没有,则js引擎会自动沿_ _proto_ _属性去父元素查找。
如果在父元素中找到了想要的属性或方法,则和访问子对象的方法一样调用。

强调:构造函数中一定不要包含方法的定义。所有方法都应该集中定义到原型对象中一份。所有子对象共用。

2. 原型中this的指代

原型对象(prototype)中的this->将来调用这个共有函数的.前的某个子对象。——谁调用指谁

//构造函数中不能定义方法
function Student(sname,sage){this.sname=sname;this.sage=sage;}//要定义的方法全部写在Student的原型对象中,成为公共函数
Student.prototype.intr=function(){// this在此处只定义,不调用console.log(`I'm ${this.sname}, I'm ${this.sage}`)
}var erya1=new Student("erya1",11)
var erya2=new Student("erya2",12);// 调用公共函数,this被调用,this->'.'前对象erya1
erya1.intr();
// 调用公共函数,this被调用,this->'.'前对象erya2
erya2.intr();

验证子孩子的父亲是不是Student的老公

console.log(erya1.__proto__==Student.prototype);
console.log(erya2.__proto__==Student.prototype);

结果显示true

3.自有属性和共有属性

  1. 自有属性: 保存在子对象内部,只归当前子对象自有的属性
  2. 共有属性: 保存在父对象(原型对象)中,归多个子对象共有的属性

以下图为例,图中自有属性是name,共有属性是intr

3. 获取属性值,都可用: 子对象.属性名
如果js引擎发现,要使用的属性不在子对象中,则自动延_ proto _属性向父对象继续查找要用属性。

function Student(sname,sage) {this.sname=sname;this.sage=sage;
}Student.prototype.className="1班";
var erya1=new Student("erya1",11);
var erya2=new Student("erya2",12);console.log(erya1);
console.log(erya2);
console.log(erya1.className, erya2.className);//1班 1班

4. 修改属性值
1). 自有属性:
子对象.属性名=属性值;

2). 共有属性:
必须用原型对象修改:构造函数.prototype.共有属性=新值

错误后果:不会修改原型对象中的共有属性,而且还会给当前子对象添加一个同名的自有属性。
在这个属性的使用上,这个子对象无法再与其他子对象同步

//修改属性值
//错误:
// lilei.className="初二2班";
//正确:
Student.prototype.className="2班";
console.log(erya1.className, erya2.className);//2班 2班

4.内置类型的原型对象:

内置类型: ES标准中规定的,浏览器已经实现,我们可以直接使用的类型。

11种内置类型 (背)

  • String, Number, Boolean
  • Array, Date, RegExp, Math(不是类型,已经是一个{}对象)
  • Error
  • Function Object
  • global(全局作用域对象,在浏览器中被window代替)

类型:
一种类型=构造函数+原型对象

  • 构造函数:创建子对象
  • 原型对象:为所有子对象保存共有成员(属性值和方法)

tip:
1.其实11种内置类型中的九种类型,也都由构造函数和原型对象组成。也都可以new创建子对象。
2.查看该类型共有哪些API:类型名.prototype
3.原型对象中没有提供的功能,我们可以自定义一个函数,保存到原型对象中:
构造函数.prototype.新方法=function(){...}

5. 原型链:

原型链:由多级父对象逐级继承形成的链式结构
保存着一个对象可用的所有属性和方法
控制着属性和方法的使用顺序:
先自有再共有——就近原则!

二、多态

定义:同一个函数,在不同情况下表现出不同的状态

分类:

  • 重载overload :同一个函数,输入不同的参数,得到不同的返回值
    Javascript(二)——函数(重载、回调)
  • 重写override

1.override重写

function Student(sname,sage){this.sname=sname;this.sage=sage;
}//在顶级的父类型Object中的原型对象已经有一些共有方法(toString……)
//在Student中为所有学生重写好用的toString()
Student.prototype.toString=function(){return `{ sname:${this.sname}, sage:${this.sage} }`
}var erya=new Student("erya",11)
var arr=[1,2,3];
var now=new Date();console.log(erya.toString())
console.log(arr.toString())
console.log(now.toString())

输出结果如下:

图解

①调用函数时,Student、Array和Date对象的构造函数和原型对象以及生成的子对象继承关系如下:

②隐藏存在一个最顶层父类型对象Object,在Object的原型对象中有自带的方法,以toString()为例,每个子对象都可以直接使用Object的toString方法
但是有时候直接使用不满足我们需求,这时可以对其进行重写

③重写
Array对象在它的原型对象中重写其父级的toString()函数,arr就可以调用重写后的toString

Data对象与Student对象同理

JavaScript——面向对象之继承(原型对象)与多态(重载、重写)相关推荐

  1. 深入理解Javascript中构造函数和原型对象的区别

    在 Javascript中prototype属性的详解 这篇文章中,详细介绍了构造函数的缺点以及原型(prototype),原型链(prototype chain),构造函数(constructor) ...

  2. JavaScript面向对象——深入理解原型继承

    JavaScript继承--深入理解原型继承 原型继承 // 父类function School (name, address) {this.name = namethis.address = add ...

  3. JavaScript面向对象——多继承的实现与理解

    JavaScript面向对象--实现并理解JavaScript多继承 多继承: 说明:在JavaScript中继承是依赖于原型prototype链实现的,只有一条原型链,理论上是不支持继承多个父类的. ...

  4. javascript 面向对象 new 关键字 原型链 构造函数

    JavaScript面向对象 JavaScript 语言使用构造函数(constructor)作为对象的模板.所谓"构造函数",就是专门用来生成实例对象的函数.它就是对象的模板,描 ...

  5. 关于JavaScript的Prototype及原型对象的理解

    学习JavaScript时,就一定会涉及到两个概念–prototype,原型对象.自己在做项目时可能无意中使用到,但是却没有真正去了解这个东西,在学会使用的基础上,进一步去理解它会帮助自己吸收到更多不 ...

  6. JavaScript基础09-day11【原型对象、toString()、垃圾回收、数组、数组字面量、数组方法】

    学习地址: 谷粒学院--尚硅谷 哔哩哔哩网站--尚硅谷最新版JavaScript基础全套教程完整版(140集实战教学,JS从入门到精通) JavaScript基础.高级学习笔记汇总表[尚硅谷最新版Ja ...

  7. JavaScript学习笔记之原型对象

    本文是学习<JavaScript高级程序设计>第六章的笔记. JS中,便于批量创建对象的三种模式: 1.工厂模式:用一个函数封装创建对象的细节,传入必要的参数,在函数内部new一个对象并返 ...

  8. javascript详解函数原型对象prototype与constructor

    1.原型模式 首先我们来谈谈prototype属性,也就是原型属性.每当我们创建一个函数时,函数内部都会自动生成一个指针(既自动生成一个属性就是我们说的prototype),这个指针指向指向原型对象, ...

  9. javascript 面向对象(实现继承的几种方式)

    欢迎大家关注我的公众号[老周聊架构],Java后端主流技术栈的原理.源码分析.架构以及各种互联网高并发.高性能.高可用的解决方案. 1.原型链继承 核心: 将父类的实例作为子类的原型 缺点: 父类新增 ...

最新文章

  1. 《Ember.js实战》——2.3 计算属性
  2. iOS开发 - OC - block的详解 - 深入篇
  3. 微软正式开源Blazor ,将.NET带回到浏览器
  4. 团队文化之表扬和批评
  5. jQuery lazyload 懒加载
  6. 打印二叉树的边界节点
  7. 精密空调主要部件是干啥用的?
  8. JAVA类 与类文件
  9. 打包(归档)和压缩(包含两者的区别)
  10. CentOS6.4x64_安装Qt5
  11. Xray扫描器SQL注入检测:sqldet
  12. 在树莓派3上使用红外遥控器控制libreELEC和Raspbian系统
  13. JZOJ5460. 【NOIP2017提高A组冲刺11.7】士兵训练
  14. 苹果雪豹操作系统正式版_苹果为旧机型发布iOS 12.4.2;macOS 10.14.6发布了,Catalina还远吗?...
  15. 域名服务商自曝行业内幕:用户面临层层陷阱
  16. Blog UPUP——域名、图床与其他
  17. 前端学习笔记:CSS学习之选择器篇
  18. 安装 配置 Nginx
  19. web直传cos(腾讯云)图片视频
  20. gitlab 分支保护

热门文章

  1. Visual Web Developer 中的网站类型
  2. JavaScript为事件处理器传递参数 (转)
  3. ASP.NET极限:页面导航 (翻译)
  4. 如何在hexo中支持Mathjax
  5. C++ 单继承访问私有成员
  6. jquery概念、引入、选择器
  7. MySQL_运算符与函数
  8. 2012,新的一年,新的开始
  9. pycharm中设置显示行数
  10. Batch Normalization批量归一化