es6中class的语法糖

什么是语法糖?

语法糖(syntactic sugar)是指编程语言中可以更容易的表达一个操作的语法,它可以使程序员更加容易去使用这门语言,操作可以变得更加清晰、方便,或者更加符合程序员的编程习惯。用比较通俗易懂的方式去理解就是,在之前的某个语法的基础上改变了一种写法,实现的功能相同,但是写法不同了,主要是为了让开发人员在使用过程中更方便易懂。

es6中的语法糖有哪些?

这个话题其实很大,es6中的语法糖太多了,例如常用的箭头函数,解构赋值等都是语法糖,具体的可以看看这篇文章

es6中的class

es5和es6构造实例的区别

接下来就进入正题了,揭开es6中class的神秘面纱。首先为什么会有class的概念,在es5时期,生成实例是通过构造函数,但是如果要添加方法的话,就必须在原型上去添加,这样构造函数new出来的实例才可以用这个方法。就比如这样:

// Person为构造函数
function Person (name, age) {
    this.name = name,
    this.age = age
}

// 在构造函数的原型上添加方法
Person.prototype.getName = function () {
    return this.name
}

// 构造一个实例
var huhaha = new Person('huhaha', 21)
// 在实例上调用该方法
var myName = huhaha.getName()

console.log(myname) // huhaha

那么在es6中怎么使用class去实现它呢,先看代码再解释~

// 类中的this指向创建的实例
class Person {
    constructor (name, age) {
        this.name = name
        this.age = age
    }

    getName () {
        return this.name
    }
}

// 构造一个实例
let huhaha = new Person('huhaha', 21)
// 在实例上调用该方法
const myName = huhaha.getName()

console.log(myname) // huhaha

我们可以看到通过es6去实现,更容易理解,并且代码量也有所减少。使用这种方式,我们可以清楚的明白,前面使用了class的就是一个类,那么它就有构造实例的能力,并且constructor中放的是每个通过该类构造出来的实例都可以获得属性,在constructor外面放的是可以获得的方法。
  除了在写法上的区别,class和构造函数还有一个区别就是在class中定义的方法是不可枚举的,而在es5中原型上添加的方法是可枚举的。还有一点就是,使用class,在创建实例的时候必须使用new,而普通的构造函数是可以省略的。

class基本语法

constructor函数

constructor是类的默认方法,如果在写class时,没有添加该方法,js引擎会默认添加这个方法。通过new去构造实例时,会自动去调用该方法,该方法默认返回的是该实例对象,但是也可以指定返回的对象,比如下面的情况:

class Fun {
    constructor () {
        // 改变默认返回的内容
        return Object.create(null)
    }
}

let fun = new Fun()
// fun不是Fun的实例
fun instanceof Fun // false

静态属性

如果在类中一个属性的前面有static关键词时,就表明这个属性是静态属性。静态属性是类的属性,通过类构造的实例中是没有这个属性的,只有通过类才可以拿到这个属性。

静态方法

如果在类中一个方法的前面有static关键词时,就表明这个方法就是静态方法。静态方法的特殊性有两点:首先,在由该类创建的实例中,是不能调用该方法的,这个方法只能通过类本身去调用;其次,如果在该方法中包含this,那么this指向的是该类,下面的例子可以证明这两点:

class Person {
    constructor (name, age) {
        this.name = name
        this.age = age
    }

    getName () {
        return this.name
    }

    static age = 42

    static getAge () {
        return this.age
    }
}

let huhaha = new Person ('huhaha', 21)
huhaha.getName() // huhaha
huhaha.getAge() // TypeError: huhaha.getAge is not a function

Person.getAge() // 42

class的继承

我们知道在es5中继承的方式有很多种,最简单的方式就是通过原型链进行继承,但是就算是这种最简单的方式也会让人很容易混乱;为了解决这个问题,es6中使用extends关键字去表示继承,并在子类中使用super关键字去继承父类的内容,下面这个例子可以很好的表明es6中的继承关系:

// Father为父类
class Father {
    constructor (x, y) {
        this.x = x
        this.y = y
    }

    toString () {
        return 'string'
    }
}

// Child为子类,继承Father
class Child extends Father {
    constructor (x, y, z) {
        super (x, y) // 调用Father类中的constructor(x, y)
        this.z = z
    }

    toString () {
        return super.x + super.toString() // 通过super调用Father类中定义的方法
    }
}

在上面的例子中,我们可以看到,子类继承父类最关键的地方就是,需要在子类的constructor中使用super去继承父类,它在这里表示的是父类的构造函数,用来新建父类的this对象。这里完成继承的思想是,子类是通过先在父类中创建一个实例,拥有了父类中定义的属性和方法,然后子类再添加自己的属性和方法。这个和es5中的思想不太一致的地方在于es5中是先创建子类的this对象,然后将父类的属性和方法添加到子类的this中。通过图来简单的解释就是:

  • es6中的实现思路


    image.png
  • es5中的实现思路
image.png

之前我们有讲到类的静态属性和静态方法,当时说的是前面使用了static关键字的就是指这个类上面属性和方法,实例是拿不到的。在这里我们可以看作是这个静态的内容,只是针对于创建实例,对于子类的继承是不影响的,也就是说在子类中是可以继承到父类中的静态属性和方法的,甚至于我们可以在子类中对这些属性和方法进行覆盖。

检验父类的方法

我们可以通过Object.getPrototypeOf方法去检测子类与父类之间的继承关系,如下例:

// 检测Father是否为Child的父类
Object.getPrototypeOf(Child) === Father // true

super关键字

super关键字是实现继承最关键的内容,它有两个身份,第一个是当作函数使用,第二个是当作对象使用,这个点其实在上面的例子也有体现到,现在我们再来仔细说一说。

作为函数使用

当作为函数使用时,super表示的是父类的构造函数,我们需要注意以下几点:

  1. 在子类中必须包含super
  2. 子类中的super只能在构造函数中使用
  3. super内部的this是指向子类的,这一点可以看这里
作为对象使用

当作为对象去使用的时候,一般就是通过super去调用父类的属性和方法了,但是这里需要注意的是,使用super只能获取到父类原型中包含的属性和方法,也就是说后面通过实例添加的属性和方法是获取不到的。我们需要注意以下几点:

  1. 在静态方法中使用时,super指向的是父类而不是父类的原型对象
  2. 在普通方法中使用时,super指向的是父类的原型对象而不是父类本身
  3. 在静态方法中通过super去调用父类的方法时,this指向的是子类,而不是子类的实例
  4. 在使用super时,我们必须显式地表明作为对象使用还是作为函数使用
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容