ES6的class:
为了和其他的语言一致,JS提供了关键词class模拟传统的class,但底层的实现机制仍然是原型继承
什么是class?
集中存储一个类型的构造函数和原型对象的程序结构,即简化版的面向对象(封装,继承,多态)
为什么使用class
因为在ES5中,要定义一个类型,构造函数和原型对象方法要分着写,不符合封装的要求
什么时候使用class:
只要创建一种类型,不要先创建构造函数,也不要分着写原型对象方法,而是先创建一个class,然后将所有成员集中在class中,用class包裹原来的构造函数和方法
class的声明定义:
<script>class User{}console.log(new User())let Articla = class{}console.log(new Artical())
</script>类方法之间不需要逗号class User {show() {}get() {console.log("get method");}
}
const hd = new User();
hd.get();
3.在类方法中的构造函数的写法和我们以前写构造函数的写法是一样的,但是 注意:在类中,构造函数必须统一命名为constructor
4.class的使用和旧的JS中构造函数和原型对象方法是一样的。存储结构也是完全一样的 class就是新瓶装旧瓶
class中的共有属性问题?
在class构造函数中的变量绝对不是共有属性,而是我们用class创建对象的私有属性,如果我们想添加共有属性,可以在类的原型上添加。
class中访问器属性:
对于旧的的构造函数,在构造函数声明的时候就要保护将来声明的对象,但是访问器只是提供一个保护功能,并不能保存属性,且所有的孩子的访问器的属性都是统一的,所以访问器属性应该在原型中定义一份就可以了。
用构造函数写的一个保护属性:
<script>//声明一个构造函数function fn(name,age,sex){this.name = name; this.age = age; this.sex = sex; //一般在实列化对象之前我们就对他们设置了保护属性 Object.defineProperties(this,{_age:{ value:this.age,writable:true, enumerable:true, configurable:true,
} }) } //因为访问器的属性都是逻辑都是相同的,所以我们给他们的构造函数原型上设置就行了
Object.defineProperties(fn.prototype,{age:{get(){return this._age}, set(value){ if(value>18 && value<58){ this._age = value }else{ throw Error('超出界限')} }, enumerable: true, // 保镖要代替原属性抛头露面 configurable: false, // 保镖不能轻易被删除}})let str = new fn('liquan',19,'男')str.age=50console.log(str);
</script>
就有点复杂,但是在类中声明访问器属性就比较简单直接写在类里面就行了
// 声明一个类class User{constructor(name,age,sex){this.name = name;this.sex = sex;this.age = age;//为对象的数据属性设置保护Object.defineProperties(this,{_age:{value:this.age,writable:true,configurable:true}})}//直接把访问器属性写在外面就好了get age(){return this._age}set age(value){if(value>18 && value<58){this._age = value;}else{throw Error('超出界限')}}}let user = new User('李权',19,'男');user.age=50console.log(user);
类的继承:
当父级的类和子集的类有相同的数据结构的时候,可以调用类的继承 用extends让自己继承父级的,取代了Obeject.setPrototype(a,b)
并且注意如果当使用extends这个方法,会附带一个关键词super,调用父级的构造函数,注意:super一定在调用子集的父级之前调用
//实现一个飞机大战的数据结构//敌军降落伞的位置class Enemy{constructor(x,y){this.x = x;this.y = y;}fly(){console.log(`敌军在${this.x},${this.y}位置`);}}//击落敌军得分class Plan extends Enemy{constructor(x,y,score){super(x,y); //调用父级的构造函数this.score = score;}getScore(){console.log(`击落敌军得到${this.score}分`);}}//击落降落伞得到什么奖励class San extends Enemy{constructor(x,y,aware){super(x,y);this.aware = aware;}getAware(){console.log(`击落降落伞得到${this.aware}奖励`);}}let str = new Enemy(100,100);str.fly()let str1 = new Plan(200,200,100)str1.fly()str1.getScore()let str2 = new San(250,250,'射速加快')str2.fly()str2.getAware()