JS 中的类

92 阅读3分钟

上一篇 : 从原型到继承 - 掘金 (juejin.cn)

class的基本语法

class的本质是一个函数

首先,我们要明确一点,那就是 class 的本质是一个函数,且内部操作为原型操作。

image.png

image.png

可以看到这两个里面的结构非常相似,可以说几乎是一模一样,且如果我们使用 typeof User 我们会在控制台上得到一个 Function 的结果。

所以我们说,class 类其实就是将 原型与继承进行了一个封装,使对 函数原型 的操作更加的方便。

class的定义与传参

下面,我们来简单的介绍一下 class 类的基本语法。

image.png

image.png

class中的方法不能遍历

image.png

image.png

我们之前在原型中讲述了,对象的原型中有一个属性叫做 enumerable 如果这个值为 true,则表示可以遍历,反之不行。在 class 中,这个属性被手动的设置为 false,所以它的方法不能被遍历。

静态属性的使用

首先,我们了解一下函数中的静态属性

function Web(name){
    this.name = name
}

Web.url = 'http://127.0.0.1'

上面的 name 是每个实例化对象自己传进去的,各个实例化对象并不相同。但是 url 这个属性是所有实例化对象共同拥有的。这里的 url 就是函数的静态属性。

接下来我们来了解一下 类中静态属性 的用法。

image.png

image.png

这里的 host 属性,所有实例化出来的对象都能使用。

静态方法的使用

同样的,我们先从函数入手。

function User(){}

User.prototype.name = function(){
    console.log("prototype.name")
}

User.show = function(){
    console.log("User.show")
}

上面的 name 函数在 User 的原型上面,各个实例化对象都能调用。但是 show 这个属性只能使用 User.show()。这里的 show 就是函数的静态方法。

下面,我们来了解一下 类的静态方法。

image.png

很显然,这里的 show 静态方法,也只能使用 User.show 来调用。

在class中使用访问器

image.png

class的数据保护

使用symbol定义保护属性

image.png

symbol 的值是唯一的,我们使用getter和setter,可以象征性的起到一定的保护作用,但值得注意的是,我们这样做,并不能做到像 c++中的protected 一样,在类外,我们仍然可以直接通过hd[HOST]去访问,只是大家不这样做罢了。

当然,这个在继承中也可以正常使用

image.png

private私有属性使用

image.png

这样我们就实现了private,当然,如果想要修改,我们同样也可以使用getter和setter

image.png

此外,对于方法,我们也可以把他设置为 private , 具体的例子看上文。

class继承

class继承的基本语法

还是一样,我们先从函数看起

image.png

这个在原型和原型链那篇文章讲过,就不过多赘述。接下来我们看看 class 继承的基本语法。

image.png

当然,上面类的继承,本质还是原型和原型链,也就是最开始的函数写法,只不过更严谨,更方便。

super原理分析

image.png

值得注意的是 this 指针永远指向调用他的对象。

image.png

super在多继承中的使用

image.png

image.png

此时,控制台陷入了一个死循环。

原因是:当我们调用 xj.show() 的时候,会调用到 hd 中的 show 方法,而此时 hd 中的 this 指向 xj 这样,又将函数指回了 xj ,循环往复,永远不会指向 common

image.png

mixin混合模式技巧

let Tool = {
    max(key) {
        return this.data.sort((a,b) => b[key] - a[key])[0]
    }
}

let Count = {
    count(key) {
        return this.data.sort((a,b) => b[key] - a[key])[0]
    }
}

class Lesson {
    constructor(lessons) {
        this.lessons = lessons
    }
    get data(){
        return this.lessons
    }
}

const data = [
    {name: "js",price: 100,click:188},
    {name: "mysql",price: 212,click:88},
    {name: "vue.js",price: 98,click:288}
]

// 将 Tool 中的属性 合并到 Lesson.prototype 中去
Object.assign(Lesson.prototype,Tool)
Object.assign(Lesson.prototype,Count)
let hd = new Lesson(data)
console.log(hd.count("price"))

我们将 ToolCount 的属性全部合并到 Lesson.prototype 中去了,实现了多继承。

结语

好啦,本次分享就到这里。

文章如果有不正确的地方,欢迎指正,共同学习,共同进步。

若有侵权,请联系作者删除。