一、class类
1、ES6中class类
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。
通过class关键字,可以定义类。
基本上,ES6的class可以看做只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
二、ES5中定义对象
1、ES5通过构造函数实例化对象的语法
//手机
function Phone(brand, price){
//对实例对象的属性做初始化
this.brand = brand;
this.price = price;
}
//添加call方法
//通过原型对象来去添加,这样可以重用
Phone.prototype.call = function(){
console.log("我可以打电话!");
}
//实例化对象
let Huawei = new Phone('华为', 5888);
//调用call方法
Huawei.call();
//打印Huawei这个变量
console.log(Huawei);
三、class声明类,constructor定义构造函数初始化
1、constructor方法
当我们在用【new + 类名】的时候,就会自动去执行实例对象上的constructor方法。
2、构造方法固定叫constructor,名字不能修改
3、类的自定义方法,不能使用ES5的对象完成形式,call: function(){...}
必须是【方法名 + 小括号 + 花括号】
4、例子
class Phone{
//构造方法,名字不能修改
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用该形式
//不能使用ES5的对象完成形式,call: function(){...}
call(){
console.log("我可以打电话!");
}
}
let onePlus = new Phone("1加", 1999);
console.log(onePlus);
四、static定义静态方法和属性
1、ES5的方式举个例子
先定义一个函数对象,在用new生成一个实例对象。函数对象和实例对象是两个不同的对象:
(1)实例对象是没有函数对象(构造函数)上的属性的。
(2)实例对象和函数对象原型上的属性是相通的。
(3)实例对象的属性和函数对象的属性是不相同的。函数对象里的属性是属于函数对象的。
对于函数对象里这样的属性,我们称之为静态成员。
换到面向对象里,这样的成员是属于类的,而不属于实例对象。
//定义一个构造函数,构造函数本身也是一个对象
function Phone(){
}
//在函数对象上添加属性和方法
Phone.name = '手机';
Phone.change = function(){
console.log("我可以改变世界!");
}
//实例对象
let nokia = new Phone();
//函数对象原型上修改属性
Phone.prototype.size = 5.5;
console.log(nokia.size);
console.log(nokia.name);
console.log(nokia.change());
2、static关键字方式
class Phone{
//静态属性
static name = '手机';
static change(){
console.log("我可以改变世界!");
}
}
let nokia = new Phone();
console.log(nokia.name);
console.log(nokia.change());
同样static定义的属性和方法是属于类的,不属于实例化的对象。
五、extends继承父类
1、ES5通过构造函数来实现继承的语法
call方法实现js的继承。
//父类
//手机
function Phone(brand, price){
this.brand = brand;
this.price = price;
}
Phone.prototype.callphone = function(){
console.log("我可以打电话!");
}
//子类
//智能手机
function SmartPhone(brand, price, color, size){
//这个call方法是js Function上的方法,作用是调用一个对象的一个方法,以另一个对象替换当前对象
//this参数指向SmartPhone里的实例对象
Phone.call(this, brand, price);
this.color = color;
this.size = size;
}
//设置子集构造函数的原型
SmartPhone.prototype = new Phone; //这样SmartPhone的实例对象,就会有父类的方法
SmartPhone.prototype.constructor = SmartPhone; //校正
//声明子类的方法
SmartPhone.prototype.photo = function(){
console.log("我可以拍照!");
}
SmartPhone.prototype.playGame = function(){
console.log("我可以玩游戏!");
}
const chuizi = new SmartPhone('锤子', 2499, '黑色', 5.5);
console.log(chuizi);
2、extends关键字方式
代码很简洁。贴合面向对象继承的写法。
class Phone{
//构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父类的成员属性
callPhone(){
console.log("我可以打电话!");
}
}
//子类继承父类
class SmartPhone extends Phone{
//构造方法
constructor(brand, price, color, size){
//调用父类构造方法
super(brand, price);
this.color = color;
this.size = size;
}
photo(){
console.log("我可以拍照!");
}
playGame(){
console.log("我可以玩游戏!");
}
}
const xiaomi = new SmartPhone('小米', 799, '黑色', '4.7');
console.log(xiaomi);
xiaomi.callPhone();
xiaomi.photo());
xiaomi.playGame();
六、子类对父类方法的重写
1、在子类中重写父类的方法
//子类继承父类
class SmartPhone extends Phone{
//构造方法
constructor(brand, price, color, size){
//调用父类构造方法
super(brand, price);
this.color = color;
this.size = size;
}
photo(){
console.log("我可以拍照!");
}
playGame(){
console.log("我可以玩游戏!");
}
//重写父类的方法
callPhone(){
console.log("我可以视频通话!");
}
}
这里重写了callPhone()方法。
在js的class语法里,子类是不能直接调父类的同名方法的。
七、calss中getter和setter设置
1、get和set
对对象的一个属性,进行方法的绑定。当对某个属性获取时执行get函数,设置时执行set函数。
//get和set
class Phone{
//类内部缓存price值
_price = 0;
get price(){
console.log("价格属性被读取了");
return this._price; //这个get函数的返回值,就是这个属性的值
}
set price(arg){
console.log("价格属性被修改了");
this._price = arg;
}
}
//实例化对象
let s = new Phone();
//获取
console.log(s.price);
//赋值
s.price = 2899;
console.log(s.price);
因为set price()无法直接修改get price()返回的值,需要一个第三方值_price缓存price。