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