前端学习:ES6中的class类
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;
知识点:
1. class 声明类;
2. constructor 定义构造函数初始化;
3. extends 继承父类;
4. super 调用父级构造方法;
5. static 定义静态方法和属性;
6. 父类方法可以重写;
1.用传统的es5中的构造函数实现类:
// es5中构造函数实例化对象
// 以手机为例
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
// 添加方法
Phone.prototype.call = function () {
console.log("我可以打电话");
}
// 实例化对象
let Huawei = new Phone("华为", 5999);
Huawei.call();
console.log(Huawei);
2.用class实现
class Phone {
// 构造方法 名字不能修改
// constructor()方法是会自动执行的。
// 当我们使用new方法实例化函数时constructor()是可以自动执行的
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 方法必须使用该语法,不能使用ES5的对象完整形式
call() {
console.log("我可以打电话!!!");
}
}
let onePlus = new Phone("1+", 1999);
console.log(onePlus);
3.类的静态成员
1)es5中
function Phone() {
}
Phone.name = "手机";
Phone.change = function () {
console.log("我可以改变世界");
}
let nokia = new Phone();
console.log(nokia.name);
nokia.change();
上述代码运行结果可以看出实例对象是没有构造函数对象拥有的属性的,同时实例对象也没有构造函数对象拥有的属性的,所以说实例对象是实例对象,构造函数对象是构造函数对象,他们的属性是不相通的。
但是实例对象属性与构造函数原型对象的属性是相通的;
Phone.prototype.size = "5.5inch";
let nokia = new Phone();
console.log(nokia.name);
console.log(nokia.size);
nokia.change();
上述代码表示实例对象属性与构造函数原型对象的属性是相通的。
2)es6中
class shouji {
// 静态属性
static name = "手机";
static change() {
console.log("我可以改变世界");
}
}
let Huawei = new shouji();
console.log(Huawei.name);
console.log(shouji.name);
对于class中的静态属性属于的是类,而不属于实例对象,关键字为static
4.类继承
1)es5中构造函数类的继承
function Phone(brand, price) {
this.brand = brand;
this.price = price;
}
Phone.prototype.call = function () {
console.log("我可以打电话");
}
// 智能手机
function SmartPhone(brand, price, color, size) {
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
// 设置子级构造函数的原型
SmartPhone.prototype = new Phone;
SmartPhone.prototype.constructor = SmartPhone;
// 声明子类的方法
SmartPhone.prototype.photo = function () {
console.log("我可以拍照");
}
SmartPhone.prototype.playGame = function () {
console.log("我可以玩游戏");
}
const chuizi = new SmartPhone("锤子", 2499, "黑色", "5.5inch");
console.log(chuizi);
2)es6中构造函数类的继承
class Phone {
// 构造
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log("我可以打电话!");
}
}
// 子类SmartPhone加上extends后继承父亲Phone的属性
class SmartPhone extends Phone {
// 构造方法
constructor(brand, price, color, size) {
// 调用父类的构造方法初始化
super(brand, price);// 通过super调用父亲的构造函数
this.color = color;
this.size = size;
}
photo() {
console.log("我可以拍照");
}
playgame() {
console.log("我可以玩游戏");
}
}
const xiaomi = new SmartPhone("小米", 2999, "黑色", "5.5inch");
console.log(xiaomi);
5.子类对父类的重写
子类中出现了与父类相同的方法名,子类会对父类重写,并不能直接调用父类的方法
class Phone {
// 构造
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
// 父类的成员属性
call() {
console.log("我可以打电话!");
}
}
// 子类SmartPhone加上extends后继承父亲Phone的属性
class SmartPhone extends Phone {
// 构造方法
constructor(brand, price, color, size) {
// 调用父类的构造方法初始化
super(brand, price);// 通过super调用父亲的构造函数
this.color = color;
this.size = size;
}
photo() {
console.log("我可以拍照");
}
playgame() {
console.log("我可以玩游戏");
}
call() {
console.log("我可以进行视频通话");
}
}
const xiaomi = new SmartPhone("小米", 2999, "黑色", "5.5inch");
console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
call的运行结果为:我可以进行视频通话。证明了子类只能对父类进行重写。
6.class中的get与set
对对象的一个属性进行方法的一个绑定,例如get当对某一个属性进行获取时,执行get对应的函数,当对某一个属性进行设置时,执行set对应的函数
class Phone {
get price() {
console.log("价格属性被读取了");
return "iloveyou";
}
set price(newval) {
console.log("价格属性被修改了");
}
}
// 实例化对象
let s = new Phone();
s.price = "free";
console.log(s.price);
上述代码没有构造函数,类中没有构造函数也是合法的。上述代码是只要我读取s的price属性就会执行get price里面的函数,而且函数的返回值就是我们属性(此处是price)的值。
set的方法与get类似,当我们对price属性进行一个赋值的时候就会调用set这个方法对用的price函数。这里一定要注意,set中的属性一定要传入参数。
get的使用场景:通常是对对象的动态属性进行封装,这个属性是变化的
set的使用场景:通常是对对象设置的值是否为合法