快速掌握ES6的class用法
1.如何构造?
先复习一下es5常用的构建类的方法:
-
首先es5的写法使用原型进行对象的方法的,为什么不在构造函数里添加方法呢?
因为实例化对象的时候,会重复的建立好多相同的方法,浪费资源。所以需要把对象的方法挂载到prtotype里。
-
关于new和this的绑定问题,可以大概简化为:
- 首先通过new生成一个新的对象
- 然后让这个对象绑定到构造函数的this中去
- 然后绑定这个构造对象的原型对象上
- 最后把这个对象返回给前面定义的对象
那么接下来看例子吧:
fuction Animal(name,age){
this.name = name
this.age = age
// 这样是浪费资源的
// this.eat = function(){
// console.log("今天我吃饭了")
// }
}
// 正确做法
Animal.prototype.eat=function(){
console.log("今天我吃饭了")
}
然后上ES6的class,class很明显就简化了这个操作
cosnt dog = new Animal("wangcai",2) // 会报错,ES6为了修改陋习,和let和const一样,class不会提升.
class Animal{
constroctor(name,age){
this.name = name
this.age = age
}
eat(){
console.log("今天我吃饭了")
}
}
cosnt dog = new Animal("wangcai",2) //正确位置
另外class还添加了静态方法,set,get等操作。
class Animal{
constroctor(name,age){
this.name = name
this.age = age
}
eat(){
console.log("今天我吃饭了")
}
set name(value){
this.tempname ="老铁"+value
}
get name(){
return this.tempname
}
static introuduce(){
console.log("我现在是一个动物类")
}
}
//set() get()
const dog = new Animal("giao",2)
dog.name="agiao"
console.log(dog.name) // 老铁agiao
// 静态方法
Animal.introuduce() // 我现在是一个动物类
再说继承之前补充个小知识点,class的方法名可以通过计算属性的操作来命名
let tempname = "giao"
class Animal{
constroctor(name,age){
this.name = name
this.age = age
}
[tempname](){
console.log("一给我咧giao")
}
}
const xiaoagiao = new Animal("giaoge",30)
xiaoagiao.giao() // 一给我咧giao
2.继承
回到继承这个问题,es5是怎么继承的呢?
function Animal( name ){
this.name = name
}
Animal.prototype.break(){
console.log("叫!")
}
function Dog( name, age ){
Animal.call(this,name)
this.age = age
}
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
那么这个叫组合继承,怎么个组合法呢?
-
属性方面的继承是借用继承,可以看到
Animal.call(this,name)
就是相当于把Animal
这个函数在Dog
的构造函数里调用了一遍而已。虽然属性他们没有原型链的链式联通,但是代码拿过来给Dog
都跑了一遍,所以自然就继承了Animal
的name
属性。Animal.call(this,name)
-
方法的继承是原型式继承,众所周知,一个函数会在创建的时候生成一个原型对象,这个函数的的一个
protoype
属性指向他的原型对象,原型对象的constructor
属性指向这个函数。如果用new来新建这个函数的实例,这个实例会有一个__proto__
的属性指向函数的原型对象。所以借用函数实例会指向函数原型对象这个特性,我们将被继承的函数实例化,然后将这个实例化的对象赋给继承的构造函数的prototype
属性,这样就构成了一种链式结构。但同被继承的函数实例化是不具备constructor这个属性的,我们需要将他的constructor
指向继承的构造函数。Dog.prototype = new Animal() Dog.prototype.constructor = Dog
所以按照这个套路,我们用es5的语法,将dog
函数继承了Animal
函数的name
和break
方法.
那么ES6是怎么做的呢?
class Animal{
constructor( name ){
this.name = name
}
break(){
console.log("叫!")
}
}
class Dog extends Animal {
constructor( name, age ){
super(name)
this.age=age
}
}
现在只需要在声明Dog类的时候加一个extends Animal
,然后再在constructor构造函数里加一个super就好了。
这个super(name)
就相当于Animal.call(this,name)
了。然后关于方法的问题,自然就不用担心了,extends自动就处理好了,就不用再去用prototype
乱指了.