ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
比如 声明一个类,并声明一个该类的实例
class Student {
//constructor 构造函数
constructor(name, number){
//创建实例的时候 这里this指向当前创建的实例
this.name = name
this.number = number
this.gender = 'male'
}
sayHi() {
console.log(`${this.name} + ${this.number}`)
}
}
// 通过类 声明对象/实例
const gary = new Student('盖瑞',101)
console.log(gary.name)
console.log(gary.number)
console.log(gary.gender)
gary.sayHi()
Class可以通过extends关键字实现继承;这比ES5的通过修改原型链实现继承,要清晰和方便很多。
//继承
//定义一个父类
class People {
constructor(name) {
this.name = name
}
eat() {
console.log(`${this.name} eat`)
}
}
//子类一
class Student extends People {
constructor(name, number) {
//通过子类的super函数 把属性传递给父类的constructor函数进行处理
super(name)
this.number = number
}
sayHi() {
console.log(`${this.name} + ${this.number}`)
}
}
//子类二
class Teacher extends People{
constructor(name, major) {
super(name)
this.major = major
}
teach() {
console.log(`${this.name} teach ${this.major}`)
}
}
const gary = new Student('盖瑞', 101)
console.log(gary.name)
console.log(gary.number)
gary.sayHi()
gary.eat()
const laowang = new Teacher('老王','计算机')
console.log(laowang.name)
console.log(laowang.major)
laowang.teach()
laowang.eat()
可以通过instanceof 来判断实例属于哪个类
console.log(gary instanceof Student) //true
console.log(gary instanceof People) //true
console.log(gary instanceof Object) //true Object相当于顶级
console.log([] instanceof Array) //true
console.log([] instanceof Object) //true
console.log({} instanceof Object) //true
// class 实际上是函数,是语法糖
console.log(typeof People) //'function'
console.log(typeof Student) //'function'
// 隐式原型 - 显示原型
console.log(gary.__proto__)
console.log(Student.prototype)
console.log(gary.__proto__ === Student.prototype) //true
所以,简单来说可以这样理解:
1.每个class都有显示原型prototype。
2.每个实例都有隐式原型__proto__。
3.实例的__proto__ 指向对应class的prototype。
那么,原型的规则:
获取属性gary.name 或者 执行方法 gary.sayHi()时,
先在自身属性和方法里寻找,找到了直接获取或执行。
如果没有,就自动在__proto__中去查找。
那么类Student是继承于类People的,所以
console.log(Student.prototype.__proto__)
console.log(People.prototype)
console.log(People.prototype === Student.prototype.__proto__) //true
所以当在自身属性跟方法中找不到的时候,就会顺着__proto__一级级往上寻找
于是,当你输出gary.hasOwnProperty(‘sayHi’)时,输出为false。
这也就是深拷贝中为什么在递归里面要先用hasOwnProperty来判断一下拷贝的属性或者方法是不是拷贝对象自身的。
Object作为顶级对象,就没有隐式原型了,所以可以说Object.prototype就是原型链的顶端,原型链到此结束。
Object.prototype.__proto__ //null
class是ES6的一个语法规范,由ECMA委员会发布的,委员会只规定语法规则,不管实现,所以以上的实现方式都是浏览器的V8引擎的实现方式,这也是主流。