es2016-Class类

简介: Class类


ES5中类的创建


es5中的类是通过function来模拟实现的


对于在Es6以前定义类是可以通过以下方法来实现的


let Animal = function(type) {

   this.type = type;

   this.eat = function(){

       console.log('i can eat food')

   }

}


如上,定义一个名为Animal的类,类中声明一个属性type以及一个方法eat.

以下,通过new Animal 生成这个类的实例


let cat = new Animal('cat')

let dog = new Animal('dog')


如此,我们声明了两个Animal实例,一个cat,一个dog.但是在这里有一个弊端,就是eat方法在这里应该是做为一个公有方法,但是在这里当我们创建实例的时候,eat方法在两个实例创建的时候都被分别创建了.

如此,可以改良为:


let Animal = function(type) {

   this.type = type;

}

Animal.prototype.eat = function(){

   console.log('i can eat food')

}


let cat = new Animal('cat')

let dog = new Animal('dog')


//typeof

console.log(typeof Animal)  //function


当然了,在这里,eat已经变成了一个公有的方法被放在了原型链中,那么需要如何直接修改它呢?

可以通过以下方法来进行实现


dog.constructor.prototype.eat = function () {

  console.log('is edit')

}


ES6中类的创建


对于ES6中的类的创建,ES6为我们提供了一个想法方便的API,即class,不必再使用繁琐的function来进行模拟


创建方法如下:


class Animal {

   constructor(type){ //构造函数,对象私有的东西

       this.type = type;

   }

   eat(){//方法

       console.log('i can eat food')

   }

}

let dog = new Animal('dog')

let cat = new Animal('cat')


// typeof

console.log(typeof Animal)  //function


这种方法创建的类,与es5中改良后的是没有区别的,其实在这里,是es6就是一个es实现的语法糖

具体,可以通过typeof来进行操作,二者都是function


不过需要注意的是,在这里我们如果要修改类中的公共方法的话,也是可以采用和es5一样的方法的,但是,一旦我们进行了修改之后,其它的实例对象中的eat方法也会随之改变。(因为我们在这里是直接修改的原型链中的方法)

class Animal {

 constructor(type) {

   this.type = type;

 }

 eat(){

   console.log('I can eat food');

 }

}


let dog = new Animal('dog')

let cat = new Animal('cat')

console.log(dog);


dog.eat = function() {

 console.log('test');

}


dog.eat(); //test

cat.eat(); //I can eat food


class Animal {

 constructor(type) {

   this.type = type;

 }

 eat(){

   console.log('I can eat food');

 }

}


let dog = new Animal('dog')

let cat = new Animal('cat')

console.log(dog);


dog.constructor.eat = function() {

 console.log('test');

}


dog.eat(); //test

cat.eat(); //test


getter 与 setter


在es6中,允许我们将类的属性放在类的顶层中,但是放至顶层时,必须要放上get 或者 set 分别对应getter与setter


let _age = 4;

class Animal {

   constructor(type){ //构造函数,对象私有的东西

       this.type = type;

   },

   get age(){  //属性--只读

       return _age;

   }

   set age(val){   //属性--可以修改

       if(val <8 && val > 4){

           _age = val  //这里不可以使用this.age=val,会陷入死循环,即返回值与出入口的名字不可以一样

       }

   }

   eat(){//方法

       console.log('i can eat food')

   }

}


这里是使用了闭包的思想来进行实现的,因为目前es6还不支持直接设置私有属性


为类添加静态方法


所谓静态方法,就是直接从对象实例上无法访问,但是可以通过类来进行访问的方法

而实例方法,则是直接可以通过实例来进行访问的方法


ES5中为类添加静态方法


let Animal = function(type) {

   this.type = type;

   this.eats = function(){}    //实例方法

}

Animal.prototype.eat = function(){ //实例方法

   Animal.say()    //调用静态方法,直接使用类来引用

   this.say()  //this.say is not a function,静态方法在实例中是不存在的

   console.log('i can eat food')

}


Animal.say = function(){    //静态方法,直接挂载在类上

   console.log('i can say english')

}


es5中的调用方法如下:


let cat = new Animal('cat')

dog.eat()

//log

//i can say english

//i can eat food

dog.say()   //dog.say is not a function,即静态方法在实例对象中是不存在的


ES6中为类添加静态方法


es6中的写法与es5中的写法是有区别的,有专门的语法识别是否是静态方法


class Animal {

   constructor(type){

       this.type = type;

   }

   eat(){

       Animal.say()    //引用静态方法

       console.log('i can eat food')

   }

   static say(){   //static 定义静态方法

       console.log('i can say english')

   }

}

let dog = new Animal('dog')

dog.eat()

//log

//i can say english

//i can eat food


es6中与es5中类的静态方法,仅是定义的时候有所区别,引用的方法二者一致的


类的静态方法拿不到当前的实例对象!

静态方法与实例方法之间本身没有优缺差异,需要根据不同的场景来使用


类的继承


ES5中实现


es5中想要实现类的继承有很多种方法,只展示一种,只为和es6作对比


let Animal = function(type) {

   this.type = type;

   this.eats = function(){}    

}

Animal.prototype.eat = function(){

   Animal.say()      

   console.log('i can eat food')

}

Animal.say = function(){

   console.log('i can say english')

}


let Dog = function(){   //Dog类在这里将会继承Animal类

   //在这里需要初始化父类的构造函数

   Animal.call(this,'dog')    //用call改变this.的指向,这里只实现了部分继承,原型链上的还没有拿过来

   this.run = function(){

       console.log('i can run')

   }

}

Dog.prototype = Animal.prototype    //实现原型链继承(引用类型*)


let dog = new Dog('dog')

dog.eat()  

//log

//i can say english

//i can eat food


ES6中实现


在es6中使用了extends关键字来实现继承


class Animal {

   constructor(type){

       this.type = type;

   }

   eat(){

       Animal.say()  

       console.log('i can eat food')

   }

   static say(){  

       console.log('i can say english')

   }

}


class Dog extends Animal {  //dog是Animal的子类

  // super(type) //初始化父类构造函数

   

   //如果子类中也有自己的属性,需要写构造函数

   constructor(type){

       super(type) //必须放在最前面,type可以是亦是,可以是固定的

       this.weight = 5;

   }


}


let dog = new Dog('dog')

dog.eat()

//log

//i can say english

//i can eat food


参考资料



更多


目录
相关文章
|
5月前
ES6中的class类 及 递归
ES6中的class类 及 递归
27 3
ES6学习(7)class
ES6学习(7)class
|
4月前
|
存储 JavaScript 前端开发
ES6 class 类
【7月更文挑战第27天】
21 1
|
JavaScript
对TS里接口、extends和类的理解
对TS里接口、extends和类的理解
93 1
|
存储 JavaScript
【TS】class类和接口
【TS】class类和接口
110 0
ES6 class使用方法
ES6 class使用方法
67 0
|
JavaScript
【ES6】类
【ES6】类
55 0
|
JavaScript Java C++
ES6-Class如何优雅的进行“糖化”
这是一篇番外篇,其实他的主线是由一篇ES6-Class科普文章引发的“惨案”。虽然是番外篇,但是有些剧情还是不容错过的。 现在我们来进入番外篇的主线:ES6的Class是ES5构造函数的语法糖。