js中的继承:
Object是所有对象的父级/父类型/超类型,js中所有的对象都直接或间接的继承自Object.
继承有两种方式:接口继承和实现继承,js中只支持实现继承,实现继承主要依赖原型链来完成.
说明 : 其他语言的继承是通过类来实现,js中没有类的概念,js中的继承是某个对象继承另一个对象,是基于对象的继承.
一.JS实现继承方式
(1)属性拷贝(混入式继承)
(2)原型式继承
(3)原型链继承
(4)借用构造函数继承 经典继承 伪对象继承
(5)组合继承
(6)通过特定的方法实现继承
(7)内容拷贝
1.属性拷贝(混入式继承)
属性拷贝:
存在问题: 如果父对象中有引用类型,子对象和父对象的该属性会共享一份数据,修改其 中一个影响另外一个
函数拷贝:Object.assign(目标对象,要拷贝属性的对象(多个))------>ES6支持
Object.assign(o,obj1,0bj2)
2.原型式继承(不是严格意义上的继承)
(1)利用构造函数创建出来的对象可以使用原型对象的属性和方法
(2)替换原型
(3)设置子构造函数的原型对象时是父构造函数的原型:student.prototype=person.prototype
存在问题:1)只能获取父构造函数的原型对象的属性和方法,不能获取实例的属性和方法
2)无法修正构造器属性
3.扩展内置对象
Object Array Date Function String Number Boolean
通过这个方式可以扩展内置构造函数,但不建议这样做,在实际开发中很多人开发,项目的代码量非常庞大,如果每个人都通过这个方式扩展对象,可能会出现方法被覆盖等安全问题,不方便项目管理问题
(1)安全的扩展内置对象
a.提供一个构造函数(自己写的)
b.设置这个构造函数的原型对象是内置构造函数的一个实例
安全扩展内置对象图解:
3.原型链继承
1)每一对象都是由构造函数创建的
2)每一个构造函数都有自己的原型对象
3)构造函数的原型对象也是一个对象
4)构造函数的原型对象也有自己的构造函数
5)构造函数原型对象的构造函数也有自己的原型对象
6)构造函数原型对象的构造函数的原型对象也是一个对象,也有自己的构造函数
以上就形成了一个人链式结构,这个就称为原型链.
原型链的顶端是Object.prototype
Object.prototype._proto_=null
A.原型链属性的访问原则:(就近原则)
1).通过对象.属性访问属性的时候,首先会查找自身,如果有直接使用;
2).如果自身没有,会查找该对象的原型对象,如果有直接使用;
3).如果没有,会查找原型对象的原型对象,如果有直接使用;
4).如果没有,就继续之前的操作,向原型链的顶端继续查找
5).直到查找到Object.prototype,如果有就直接使用,如果没有,返回undefined或者报错
B.原型链继承:
1).提供一个父构造函数和子构造函数
2).设置子构造函数的原型对象是父构造函数的实例
Student.prototype=new Person()
C.复杂的原型链示例
动物(毛色,跑) ->人(姓名,useTool)->学生(学号,学习)->男学生(性别男,打游戏)
1).提供4个构造函数
2).设置属性和方法(属性写在构造函数中,方法写在原型上)
3).设置原型链继承
4).修正构造器属性
D.原型链继承注意点:
1)在完成原型链继承后再修正构造器属性
2)在完成原型链继承后再设置原型对象的属性和方法
3)在完成原型链继承后只能通过对象的动态特性添加属性
E.原型链继承存在的问题:
1)无法传递参数给父构造函数;
2)继承过来的属性和方法会成为原型属性和方法,存在共享问题
4.Object.create()方法
Object.create会创建一个新的对象,并且设置该对象的原型对象是传入的对象(ES5才支持)
兼容性处理:
方法一
方法二:如果有create方法就直接用,如果没有就自己添加一个方法
函数封装
5.call和apply函数
1).在ES3中,系统给Function的原型添加了2个方法
Function.prototype.call
Function.prototype.apply
作用:借用其他对象的方法
参数:(1)第一个参数:实际调用方法的对象(函数内部this的绑定对象);
(2)后面的参数: a:call,参数1,参数2..... 参数列表
b:apply,[参数1,参数2.....] 参数数组
6.借用构造函数继承 经典继承 伪对象继承
1)借用构造函数继承的基本写法,解决了无法传递参数给父构造函数的问题
存在的问题:无法获取原型属性和方法
7.组合继承
1).借用构造函数继承---->只能获取实例属性和方法
2).原型式继承---->获取原型属性和方法
问题:共享同一个原型对象
8.浅拷贝和深拷贝
1)浅拷贝:地址拷贝(指针拷贝),存在数据共享问题
2)深拷贝:内容拷贝(完全拷贝)
(1)提供一个函数封装深拷贝,有两个参数,第一个是目标参数,第二个参数是要拷贝属性的对象;
(2)判断第一个参数,如果没有值就自己初始化
(3)for...in遍历第二个参数
a.如果是值类型或者是函数,直接赋值
b.如果不是值类型的数据,就再一次调用这个方法拷贝内部存储的内容
通过深拷贝实现继承
借用构造函数----->获取实例属性
深拷贝------>获取原型属性
Array.isArray(ES5才支持)
作用:判断对象时候是个数组
二.基本包装类型
1.基本包装类型:String Number Boolean
1)创建字符串对象
2)创建数值对象
3)创建布尔对象
4)特殊的方式创建
2.基本包装类型注意点
1)在比较是否相等的时候
基本数据类型怎么会有属性?
2)内部实现:
字符串 布尔 数值在访问属性或者调用方法的时候
1).内部会默认创建一个对象
2).通过这个对象访问属性或调用方法
3).得到结果后返回结果
4).销毁该对象
网友评论