CSDN话题挑战赛第2期
参赛话题:学习笔记
目录
在ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对 象的模板。通过 class 关键字,可以定义类。
基本上,ES6 的 class 可以看作只是 一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
知识点:
1) class 声明类
2) constructor 定义构造函数初始化
3) extends 继承父类
4) super 调用父级构造方法
5) static 定义静态方法和属性
6) 父类方法可以重写
constructor方法:
在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);
接下来,我们来用class实现:
lass Shouji{
//构造方法 名字不能修改
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//方法必须使用该语法, 不能使用 ES5 的对象完整形式
call(){
console.log("我可以打电话!!");
}
}
let onePlus = new Shouji("1+", 1999);
console.log(onePlus);
- constructor方法是类的默认方法,在使用 new 命令生成实例时会自动调用此方法,如果constructor方法没有被定义,则默认添加一个空的constructor方法
- constructor方法默认返回实例对象(也就是this),也可以自己设置返回的对象
class的静态成员:
静态方法和静态属性,是使用static关键字的属性和方法
function Phone() {}
Phone.name = '手机';
Phone.change = function () {
console.log('我可以改变世界');
};
Phone.prototype.size = '5.5inch';
let nokia = new Phone();
console.log(nokia.name);
nokia.change();
console.log(nokia.size);
添加属性或方法要添加在原型上(prototype),实例对象是通过原型链去找属性或方法的。
所以在这里:nokia这个实例对象是无法去获取到Phone中的name属性和change方法的,只有定义在了原型链上的size可以被这个实例对象获取到。
在class中也有这样的现象:
class Phone{
//静态属性
static name = '手机';
static change(){
console.log("我可以改变世界");
}
}
let nokia = new Phone();
console.log(nokia.name);
console.log(Phone.name);
- 静态方法中的this,指向的是类class,不是类的实例。因此静态方法只能通过类名来调用,不能通过实例来调用
- 静态方法不会被子类继承,子类不能调用
static声明的东西属于类,而不属于实例对象
class继承
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);
class的继承:
直接使用extends关键字。
class Phone{
//构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父类的成员属性
call(){
console.log("我可以打电话!!");
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand, price, color, size){
super(brand, price);// Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo(){
console.log("拍照");
}
playGame(){
console.log("玩游戏");
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
注意:继承中子类需要调用super()方法继承父类的构造方法。super()在使用过程中需要注意以下两点
(1)在访问this之前一定要调用super()
(2)如果不调用super(),可以让子类构造函数返还一个对象
重写父类的call()方法:
class SmartPhone extends Phone {
//构造方法
constructor(brand, price, color, size) {
super(brand, price); // Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo() {
console.log('拍照');
}
playGame() {
console.log('玩游戏');
}
call() {
console.log('我可以进行视频通话');
}
}
get和set方法
// get 和 set
class Phone{
get price(){
console.log("价格属性被读取了");
return 'iloveyou';
}
set price(newVal){
console.log('价格属性被修改了');
}
}
//实例化对象
let s = new Phone();
console.log(s.price);
s.price = 'free';
get:用来获取price属性。对象名.price就会调用该方法
set:用来设置price属性值。对象名.price='值' 就会调用该方法