失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > JavaScript——面向对象之继承(原型对象)与多态(重载 重写)

JavaScript——面向对象之继承(原型对象)与多态(重载 重写)

时间:2019-06-05 05:42:09

相关推荐

JavaScript——面向对象之继承(原型对象)与多态(重载 重写)

继承与多态

引入问题一、继承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->'.'前对象erya1erya1.intr();// 调用公共函数,this被调用,this->'.'前对象erya2erya2.intr();

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

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

结果显示true

3.自有属性和共有属性

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

以下图为例,图中自有属性是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, BooleanArray, Date, RegExp, Math(不是类型,已经是一个{}对象)ErrorFunction Objectglobal(全局作用域对象,在浏览器中被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——面向对象之继承(原型对象)与多态(重载 重写)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。