class:
集中保存一个类型的构造函数和原型对象的程序结构
只要在es6中想创建一种类型时,都要用class
1.用class包裹构造函数和原型对象方法
2.构造函数名/类型名要提升到class后,作为整个class的名字,同时构造函数统一去掉function,更名为constructor,其余构造函数形参和内容都保持不变
3.放在class中的方法,不用加类型名.prototype,默认就是放在原型对象中
class 类型名{
constructor(形参列表){
this.属性名=形参;
}
方法名(){
...}
}
强调class中每个成员结尾不要加任何分割
4.创建该类型的子对象,依然是var子对象=new 类型名(属性值列表)
class Student{
constructor(sname,sage){
this.sname=sname;
this.sage=sage;
}
intr(){
console.log(`我是${
this.sname},今年${
this.sage}`);
}
}
var lilei=new Student('lilei',11);
var hmm=new Student('hmm',12);
lilei.intr();
hmm.intr();
共有属性:保存在原型对象中,由该类型所有子对象共有的属性值
旧的js中,在class{}外,类型名.prototype.共有属性=共有属性值 不符合封装要求
在class中构造函数结尾:
if(类型名.prototype.共有属性===undefined){
类型名.prototype.共有属性=属性值
}
二、class中如何保护对象:
1.保护单个属性
用开关保护,保护对象的代码要写在构造函数中,且要保护的对象用this代替。
"use strict";
class Emp{
constructor(eid,ename,eage){
this.eid=eid;
this.ename=ename;
this.salary=salary;
Object.defineProperties(this,{
eid:{
writable:false,
configurable:false
}
})
}
}
var lilei=new Emp(1001,'lilei',12000);
console.log(lilei);//报错
用访问器属性保护(Es6新做法)
1.不要在构造函数中,而是在class{}中定义访问器属性
2.get和set函数变成两个独立的函数,但是名称却是相同,都是访问器属性
class Emp{
constructor(eid,ename,eage){
this.eid=eid;
this.ename=ename;
//先创建一个半隐藏的_eage属性,暂时不给属性值
Object.defineProperty(this,"_eage",{
//value:undefined
writable:true,
enumerable:false,
configurable:false
})
//再修改Emp类型的原型对象中的访问器属性eage的enumerable为true
//Object.defineProperty(this,"eage",{...}) //错误:eage是定义在class中的,保存在原型对象中。要想修改原型对象中的成员,都要用原型对象本身去修改!而不应该用某一个子对象去修改。
Object.defineProperty(Emp.prototype,"eage",{
enumerable:true
});
this.eage=eage;
}
//创建访问器属性eage,保护eage的值必须介于18~65之间
get eage(){
return this._eage;
}
set eage(value){
if(value>=18&&value<=65){
this._eage=value
}else{
throw Error(`年龄超范围了`)
}
}
}
var lilei=new Emp(1001,"lilei",25);
console.log(lilei);
保护对象结构:在构造函数结尾保护住this的结构,就等于保护住了将来每个孩子的结构。
3.两种类型间的继承:
1.问题:两个class拥有部分相同的属性结构和方法定义!
2.解决:定义一个父类型,集中保存相同部分的属性和功能
a.父类型构造函数中集中保存相同部分的属性
b.父类型class中集中保存相同部分的方法
3.问题:默认父类型class与其他类型毫无关系,子类型class无法使用父类型中的内容
4.解决:设置两种类型间继承:
a.class 子类型 extends 父类型{
constructor(…){
super(…);
this.子类型属性=…
}
}
5.示例:
使用两种类型间继承描述飞机大战游戏的数据结构:
class Flyer{
constructor(x,y){
this.x=x;
this.y=y;
}
fly(){
console.log(`飞到 x=${
this.x},y=${
this.y}位置`);
}
}
class Plane extends Flyer{
constructor(x,y,score){
//必须调用super()来请父类型构造函数帮忙补齐子类型缺少的熟悉性
super(x,y);
this.score=score;
}
getScore(){
console.log(`击落一架敌机,得${
this.score}分`);
}
}
//创建一个敌机对象
// x y score
var p1=new Plane(50,100,5);
console.log(p1);
//{x:50,y:100,score:5}
//_ _proto_ _:{
// fly(),
// getScore()
//}
p1.fly();//飞到x=50,y=100的位置
p1.getScore();//击落一架敌机,得5分