面向对象
目的
- 改善可读性
- 提升重用性
原则(开放封闭原则)
- 对于扩展是开放的(Open for extension)。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为
- 对于修改是关闭的(Closed for modification)。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码
要素
- 封装
- 继承
- 多态
实例化对象
- var object = new Object()
|
|
手动指定对象的原型链
object.proto = {…}
- 优点:简单直接
- 缺点:这是ES6的方法,IE8以下不支持
借用 new
|
|
使用Object.create(proto)
- 以proto对象为原型,创建一个新的对象
对象_原型
面向对象(OOP)
- Object oriented programming 的缩写,面向对象的程序设计,其中最重要的两个概念是类和对象
类
- 类只是具备了某些功能和属性的抽象模型(类似于模具)用于做出成品(实例化对象),在JavaScript中,本身没有类的概念,我们需要用对象模拟出类,然后用类去创建对象
对象
- 把类实例化后就是一个个对象,就像依照模具加工出一个个成品
面向对象有三个特性
- 封装性:将一个类的使用和实现分开,只保留部分接口和方法与外部联系。
- 继承性:子类自动继承其父级类中的属性和方法,并可以添加新的属性和方法或者对部分属性和方法进行重写。继承增加了代码的可重用性。
- 多态性:子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写
构造函数的方式创建一个拥有属性和方法的对象
- 当 new 一个函数的时候,这个函数就会作为构造函数创建一个对象
- 函数里面的 this 代表创建的这个对象。给 this添加属性就是给要创建的对象添加属性
- 代码执行流程如下:
- 创建一个空对象 person
- 执行构造函数。里面的 this 代表person, 给person 添加属性
|
|
原型
- 任何函数在声明后都有一个属性 prototype,对应的值是一个对象叫原型对象
- 当 new 这个函数的时候,会作为构造函数创建一个对象
- 对象里面会有一个proto隐藏属性,指向上述构造函数原型对象
- 当访问对象的属性时先从对象本身里找,找不到再从原型对象里找
|
|
特性
- 用来实现基于原型的继承与属性的共享
- 所有对象都有 proto,指向其构造函数的prototype(obj.proto === Object.prototype //true)
- 构成原型链,同样用于实现基于原型的继承,例:访问一个对象的属性时,如果在obj中找不到,那么就会沿着proto依次查找,直到找到这个属性或null
constructor
- 原型内的一个属性,指向它的构造函数
|
|
code:画出如下代码的原型图
|
|
code:创建一个 Car 对象,拥有属性name、color、status;拥有方法run,stop,getStatus
|
|
code:创建一个GoTop对象,当new一个GotTop对象则会在页面上创建一个回到顶部的元素,点击页面滚动到顶部。拥有以下属性和方法
- ct属性,GoTop 对应的 DOM 元素的容器
- target属性, GoTop 对应的 DOM 元素
- bindEvent 方法, 用于绑定事件
- createNode 方法, 用于在容器内创建节点
|
|
this原型链继承
this
- this总是返回一个对象,简单说,就是返回属性或方法“当前”所在的对象
- 只有在函数执行时才确定(变量是在定义就确定)
|
|
this的可变性
- 由于对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this的指向是可变的
|
|
this的三种使用场合
- 全局环境
- 构造函数
- 对象的方法
全局环境
- 在全局环境使用this,它指的就是顶层对象window
|
|
构造函数
- 构造函数中的this,指的是实例对象
|
|
对象的方法
- 当 A 对象的方法被赋予 B 对象,该方法中的this就从指向 A 对象变成了指向 B 对象
|
|
|
|
apply、call 、bind
- JavaScript提供了call、apply、bind这三个方法,来切换/固定this的指向
apply
- apply方法的作用与call方法类似,改变this指向,然后再调用该函数
- 唯一的区别就是,它接收一个数组作为函数执行时的参数
|
|
作用
- 指定this值和参数(参数以数组或类数组对象的形式存在)的情况下调用某个函数。其实说白了用它可以绑定一个函数然后在另一个环境中(比如另一个函数中)使用新环境给的参数(指定this值、参数)进行运算
|
|
call
- 函数实例的call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数
|
|
bind
- bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数
|
|
code:以下代码输出什么
explain
|
|
code:下面代码输出什么
explain
|
|
code:下面代码输出什么
explain
|
|
code:下面代码输出什么
explain
|
|
code:以下代码有什么问题,如何修改
|
|
explain
|
|
原型链
- 对象的属性和方法,有可能是定义在自身,也有可能是定义在它的原型对象。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链(prototype chain)
原型链的取值
|
|
原型链图
- Student 是函数,Student 创建了 s1, Student.prototype == s1.proto
- Student.prototype 是对象, Student.prototype 是由函数 Object 创建,所以 Student.prototype.proto === Object.prototype
- 当获取一个对象的属性时,先从自己身上找==> 自己的 proto 对象上找 ==> proto.proto 上找, 一直到终点
code:有如下代码,解释Person、 prototype、proto、p、constructor之间的关联
|
|
explain
- Person是一个构造函数,本身也是一个对象
- prototype是Person对象里面的一个属性,同时prototype是构造函数内部的原型对象,其拥有contructor和proto属性,其中contructor属性指向构造函数Person,proto指向该对象的原型
- p是构造函数Person构造出来的示例,也拥有proto属性,p.proto === Person.prototype
code:上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图
explain
- p.toString()方法,先从p的属性里面找,没有
- 再从p.proto中找,还是没有
- 再从p.proto.proto中找,找到了
- 这样沿着proto这个链子一路找下去,就是原型链
code:对String做扩展,实现如下方式获取字符串中频率最高的字符
expalin
|
|
code:instanceof 有什么作用?内部逻辑是如何实现的?
explain
- 判断是不是一个对象的实例,返回值是 true、false
|
|
继承
- 继承就是子类拥有父类的属性和方法
- 父类中是更加通用的属性和方法,通过继承,子类拥有父类的属性和方法,不需要重新去写这些重复的代码,提高了代码的重用性
- 想要给所有子类修改属性和方法,只要在父类中修改就能“牵一发而动全身”,所有子类都修改了,提高了代码的可维护性
- 直接给子类添加新的属性和方法,子类就会拥有这些属性和方法,表现出多态化,而父类不会被“污染”,提高了代码的独立性
继承实例
- 人: 姓名,年纪,会说话,会走路
- 程序员: 姓名, 年纪, 爱好, 会说话, 会走路,会写代码
- 女程序员: 姓名, 年纪,爱好,会说话,会走路,会写代码,女
人
|
|
程序员
|
|
女程序员
|
|
- 代码属性和方法重复,所有用继承来减少工作量
属性的继承
|
|
方法的继承
|
|
继承后的代码
|
|
|
|
hasOwnProperty
- 判断属性是不是自有属性
|
|
code:下面两种写法有什么区别
|
|
explain
- 方法一创建的实例对象,其对象自身都会有一个相同功能的printName方法,会占用多余的内存空间
- 方法二创建的实例对象,pringtName方法在Person的prototype上(相当于一个公共空间),每个实例对象可以沿原型链调用该方法,而不必创建一个相同的方法,节约了内存空间
code:Object.create 有什么作用?兼容性如何
explain
- 创建一个以该对象为原型的实例
- 兼容性:IE 9及以上支持
|
|
code:hasOwnProperty有什么作用? 如何使用
explain
- 判断一个属性是否是自身的属性,返回 true 或 false
|
|
code:如下代码中call的作用是什么
|
|
explain
- call 的作用是实现了继承,Male 继承了 Person 的方法
- call 改变了函数 Person 的执行上下文为 male对象
code:补全代码,实现继承
|
|
explain
|
|
面向对象组件
tab组件
代码
|
|
效果
懒加载组件
代码
|
|
效果图
轮播组件
代码
|
|