说说es6中的class类

71 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情

🎈大家好,我是李乐一,新人初来乍到,请多多关照~
📝小小的前端一枚,分享一些日常的学习和项目实战总结~
😜如果本文对你有帮助的话,帮忙点点赞呀!ღ( ´・ᴗ・` )比心~

写在前面

在es5中主要是通过构造函数方式和原型方式来定义一个类,在es6中引入了class类的概念,通过关键字定义类。

一、class类必须new调用,不能直接执行。

📝举个栗子

Class Info {// 定义一个名为Info的类
    // 构造函数,用来接收参数
    constructor(name) {
        this.name = name
    }
    info() {// 类的方法,不用加function,有多个方法不必用逗号隔开
        console.log(`my name is${this.name}`)
    }
}
export default Info;

class类执行会报错,而es5中的类和普通函数没有本质区别

二、class类不存在变量提升

let info = new Info();
function Info(name) {
    this.name = name;
}
Info.prototype.name = function() {
    console.log(`my name is${this.name}`)
}

三、class类无法遍历它实例原型链上的属性和方法

function Foo (color) {
    this.color = color
}
Foo.prototype.like = function () {
    console.log(`like${this.color}`)
}
let foo = new Foo()

for (let key in foo) {
    // 原型上的like也被打印出来了
    console.log(key)  // color、like
}
class Foo {
    constructor (color) {
        this.color = color
    }
    like () {
        console.log(`like${this.color}`)
    }
}
let foo = new Foo('red')

for (let key in foo) {
    // 只打印一个color,没有打印原型链上的like
    console.log(key)  // color
}

四、new.target属性

es6为new命令引入了一个new.target属性,它会返回new命令作用于的那个构造函数。如果不是通过new调用或Reflect.construct()调用的,new.target会返回undefined

function Person(name) {
    if (new.target === Person) {
        this.name = name;
    } else {
        throw new Error('必须使用 new 命令生成实例');
    }
}

let obj = {}
Person.call(obj, 'red') // 此时使用非new的调用方式就会报错

五、class类有static静态属性和方法

静态属性不能被子类继承,子类不能调用 静态属性只能通过类名调用,不能通过类的实例调用

static prop = 1 ;  // 静态属性

static静态方法只能通过类调用,不会出现在实例上;另外如果静态方法包含 this 关键字,这个 this 指的是类,而不是实例。static声明的静态属性和方法都可以被子类继承。

class Foo {
    static bar() {
        this.baz(); // 此处的this指向类
    }
    static baz() {
        console.log('hello'); // 不会出现在实例中
    }
    baz() {
        console.log('world');
    }
}

六:class继承extends

  • class通过extends关键字来继承
  • ES6继承,子类构造函数中必须使用super()。因为ES6继承是先将父类实例对象的属性和方法,加到this上面,然后再调用子类的构造函数修改这个this
  • 如果子类没有定义constructor方法,super()会默认添加上
  • 子类会继承父类的方法和属性,但是静态方法和属性必须通过子类的类名来调用

七:class的取值函数getter和存值函数setter

getter、setter就是给class的属性读值、传值用的。

取值函数getter和存值函数setter可自定义赋值和取值行为,当一个属性只有getter没有setter的时候,这个属性就是只读属性,不能赋值,第一次初始化也不行。

如果变量定义为私有的(定义在类的花括号外面),就可以只使用getter不使用setter。

let data = [1,2,3,4];  // 放在类外面,属于私有变量,可以只读取
class Person{
    // 构造函数
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    get x(){
        console.log('获得name');
        return this._name;    // get读取属性
    }
    set x(x){
        console.log("设置name");  
        this._name=x;   // set给属性赋值
    }
    get data(){
        return data;   // 只读属性,属性返回的值只能是私有变量
    }
    todoSome(){
        console.log(this.x + "的年龄是" +this.y+"岁");
    }
    static dayin(){
        console.log("dayin");
    }
}
export default Person;

使用

  var test= new this.$myutils.classtest('haha','18');
  test.x="haha3";   // 改变了实例化时候的x的值
  test.todoSome();  // 输出:haha3的年龄是18岁。这里就已经不是实例化时候的haha了
  console.log(test.data);   // 结果:打印[1,2,3,4]