继承
学习继承,需要先熟悉下this
这个概念
继承的基本原理
- 下图中,哺乳动物是人和狗的父类
- 人和狗通用哺乳动物的属性
- 每次人和狗的对象里写哺乳动物的属性都很麻烦
- 那么子类直接引用获取父类的属性就方便多了
获取父类属性
复习一下之前学的new
运算符
function b(){
this.job='student'
}
let b1 = new b()//这个时候就创建了一个对象{job: "student"}
- 再结合之前学的
call
,可以改变函数的this指向
function a(name){
this.name=name,
this.age=2,
this.leg=4
}//先制造一个构造函数
function b(){
//使用new时,自动创建空对象,并且接下来this指向这个空对象
a.call(this,1)//原本函数中的this指向的是new a()里的空对象,现在将他改为指向当前作用域的this,现在这个this即new b()里创造出的新的对象.
this.job='student'
}
let b1 = new b()//b {name: 1, age: 2, leg: 4, job: "student"}
- 这样,就可以通过改变一个构造函数this的指向,来达到继承属性的效果
获取父类的方法
上文所做的父类继承,其实只继承了父类的属性,并没有获取到父类的方法.
function a(name){
this.name=name,
this.age=2,
this.leg=4
}
a.prototype.fnagfa=function(){}
function b(){
a.call(this,1)
this.job='student'
}
let b1 = new b()
console.log(b1)
console.log(a.prototype)//{fnagfa: ƒ, constructor: ƒ}
console.log(b1.__proto__)//{constructor: ƒ}
-
给a的原型设置了个函数
fangfa()
,集合b1指向的构造函数b的原型里没有fangfa()
,可见这个设置的函数并没有被继承 -
那么如何获得父类的方法呢?
-
可以使用之前学到的
Object.create()
-
那么
Object.create()
是什么呢?他是创建一个空对象,然后把需要传递的东西塞到空对象的_proto_
里面去
function a(){
this.x=1
this.y=2
this.z=3
}
a.prototype.A1=function(){}
function b(){
a.call(this)
this.gundam='rx-78'
}
b.prototype = Object.create(a.prototype)//创造个新对象,新对象作为b的原型,然后把a的方法直接添加到b的原型对象的原型上
ES6 的继承写法
- ES6的
extends
直接继承方法
function a(name,age){
this.name=name
this.age=age
}
a.prototype.A1=function(){}
function b(name,age,){
a.call(this,name,age)
this.gundam='rx-78'
}
b.prototype = Object.create(a.prototype)
let c = new b(1,2)//name: 1, age: 2, gundam: "rx-78"}
c.A1//ƒ (){}
//ES6的方法,b继承a
function a(name,age){
this.name=name
this.age=age
}
a.prototype.A1=function(){}
//b继承于a
class b extends a{
constructor(name,age){
super(name,age)//写要继承的属性
this.gundam='rx-78'
}
A1(){}
}
let c = new b(1,2)//name: 1, age: 2, gundam: "rx-78"}
c.A1//ƒ (){}
判断属性是否为自有属性.hasOwnProperty('属性名称')
- x和gundam属性在bbb对象上,所以是true
- A1在bbb对象的原型链上,不是自有属性,所以false
Object.assign
对象拓展
- 可以将所有可枚举的属性,从一个或多个源,复制到目标对象
- 他将返回目标对象
const obj1 = {a:1,b:2}
const obj2 = {b:4,d:5}
returnObj = Object.assign(obj1,obj2)//{a: 1, b: 4, d: 5},就是对obj1操作,将后面的对象覆盖前面的,然后返回给obj1
obj1 //{a: 1, b: 4, d: 5}
obj1 === returnObj //true
小技巧
可以创建一个空数组,来达到合并成一个新对象的目的
const obj1 = {a:1,b:2}
const obj2 = {b:4,d:5}
obj3 = Object.assign({},obj1,obj2)//{a: 1, b: 4, d: 5}
obj1 // {a: 1, b: 2}
(混合)Minxin
定义
- 通过不使用继承的方式让一个类中 的方法被其他类复用
- 可以将多个类或对象混合成一个类或对象。
- 把一个对象直接混到另一个对象的原型中
const mixin=(Base,mixins)=>Object.assign(Base.prototype,mixins)//把对象通过Object.assig()混到base的原型里
Minxin
变异版
const FlyMixin=Base=>class extends Base{
canFly(){console.log('Icanfly')}
}
class a {
show(){console.log(1)}
}
const b = FlyMixin(a)
//让b继承a的原型方法,把a的方法塞到b原型的原型里
class静态属性
- 作为函数的属性,而不是创建的对象的属性
function a(){}
let b =new a()
a.color = 'yellow'
a.age=2//函数可以直接添加属性
class c {
static color = 'yellow'
}//使用static给c添加color属性
c.color//"yellow"