一、继承
继承可以使得子类具有父类的各种属性和方法,而不需 要再次编写相同的代码。在令子类别继承父类别的同时, 可以重新定义某些属性,并重写某些方法,即覆盖父类别 的原有属性和方法,使其获得与父类别不同的功能。
1.1、ES3写法
function Mammal(name) {
this.name = name
this.head = '头'
this.neck = '颈'
this.body = '躯干'
}
Mammal.prototype.birth = function() {
console.log(this.name + '生了个宝宝')
}
let animal = new Mammal('大汪')
animal.birth()
1.2、ES6写法
class Mammal {
constructor(name) {
this.name = name
}
head = '头'
neck = '额'
body = '躯干'
birth() {
console.log(`${this.name}生了个宝宝`)
}
let animal = new Mammal('大汪')
animal.birth()
二、关于js中function和class的内在关系及区别的理解
2.1、定义class
class事实上是一种特殊的funcion,就像可以定义funcion表达式和funcion声明一样,class语法也有2种形式:class表达式和class声明。
2.2、class声明
定义一个class,可以使用class关键字加上类名。需要注意的是,funcion声明和class声明有一个重要的却别:funcion声明是hosting(状态提升)的,而class不是,class需要先声明再使用。
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
三、class中body和method的定义
class的body部分包含在花括号{ }中,这里是定义class成员的地方,比如constructor和method。
3.1、constructor
constructor方法是一个特殊的方法,用来创建并初始化一个对象。在一个class中只能有一个命名为constructor的特殊方法,如果包含多个将会报错。
constructor中可以通过super关键字,调用父类的constructor方法。
3.2、prototype methods(原型方法)
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
const square = new Rectangle(10, 10);
console.log(square.area); // 100
四、获取父类属性
4.1、.call
function Human(name) {
//等价于 Mammal(name),Mammal里面的this是当前的this
Mammal.call(this, name)
this.clothes = '衣服'
}
Human.prototype.speak = function() {
console.log(this.name + '会说话')
}
let p = new Human('小明')
console.log(p.head)
console.log(p.clothes)
p.speak()
4.2、call、apply、bind
fn.call(obj, a, b, ...)
ü 等价于 fn(a, b, ...) ,执行时fn函数里面的this是传递的 obj对象
fn.apply(obj, [a, b, ...])
ü 等价于 fn(a, b, ...),执行时fn里面的this是传递的obj对 象
fn.bind(obj)(a, b, ...)
ü 等价于 fn(a, b, ...),执行时fn里面的this是传递的obj对 象
五、获取父类方法
5.1、ES3 写法
function Human(name) {
Mammal.call(this, name)
this.clothes = '衣服'
}
Human.prototype = Object.create(Mammal.prototype) Human.prototype.constructor = Human
Human.prototype.speak = function() {
console.log(this.name + '会说话')
}
let p = new Human('小明')
p.birth()
p.speak()
5.2、ES6 写法 - 多了exends 和 super
class People {
constructor(name) {
this.name = name
}
setName(name) {
this.name = name
}
sayName() {
console.log('我的名字是' + this.name)
}
}
class Doctor extends People{
constructor(name, profession) {
super(name)
this.profession = profession
}
sayProfession() {
console.log('我的职业是' + this.profession)
}
}
六、hasOwnPerperty
判断对象自身属性中是否具有指定的属性(自由属性:绑定在自身上的属性,不是在原型链上的)
let p = new Human('小明')
p.hasOwnPerperty('name') // true
p.hasOwnPerperty('speak') // false
p.hasOwnPerperty('birth') // false
七、拓展知识
7.1、Object.assign
- 将所有可枚举属性的值从一个或多个源对象复制到目标 对象
- 它将返回目标对象。
const target = { a: 1, b: 2 }
const source = { b: 4, c: 5 }
const returnedTarget = Object.assign(target, source)
console.log(target) // { a: 1, b: 4, c: 5 }
console.log(target === returnedTarget) // true
原理:object.assign 就是对target 进行处理 属性名相同就进行覆盖,没有就新增,最后聚合成一个新的对象,本身就是对target进行操作
如果想新生成一个新的对象,可以加个{ },
例如
const obj1={a:1,b:2}
const obj2={a:4,d:3}
const obj3 = Object.assign({},obj1,obj2)
// obj3 {a: 4, b: 2, d: 3}
// obj1 {a: 1, b: 2}
7.2、Mixin
定义 : 通过不使用继承的方式让一个类中的方法被其他类复用
- mixin在javascript里可以看作是一种从别的对象"借用"功能的方法。每一个新定义的对象都有一个 prototype属性,其他的对象就可以从这里"借用"功能。这里的功能可以是一个属性,也可以是一个方法。
- mixins这种借用在 javascript里非常的适用。在重用代码的时候可以使用mixins来实现继承,也可以达到类似多继承的效果。
const mixin = (Base, mixins) => Object.assign(Base.prototype, mixins)
const Fly = { // 对象
canFly() { // 省略了 canFly:function( ){
console.log('I can fly')
}
}
class Mammal {
birthChild() {
console.log('I birth a baby')
}
}
mixin(Mammal, Fly)
let m = new Mammal()
m.birthChild()
m.canFly
7.3、getter、setter
将对象属性绑定到查询/设置该属性时将被调用的函数
const people = {
firstName: 'Micheal',
lastName: 'Jackson',
get fullName( ) {
return `${this.firstName} ${this.lastName}`
},
set fullName(name) {
let nameArr = name.split(/\s+/)
this.firstName = nameArr[0]
this.lastName = nameArr[1]
}
}
console.log(people.fullName)
people.firstName = 'John'
console.log(people.fullName)
people.fullName = 'Tom Cruse'
console.log(people.lastName)
get fullName() { // funllName 当做是属性
return `${this.firstName} ${this.lastName}`
}
加了get的好处就是,调用的时候就不需要括号了 直接People.fullName
fullName:function() {
return `${this.firstName} ${this.lastName}`
}