第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開(kāi)發(fā)者教程

ES6-10 入門(mén)教程

ES6+ Class

1. 前言

上一節(jié)我們主要回顧了在 ES5 中使用構(gòu)造函數(shù)的方式實(shí)現(xiàn)類(lèi)了,并說(shuō)明了如何實(shí)現(xiàn)類(lèi)的繼承。從上一節(jié)的講解中,構(gòu)造函數(shù)去實(shí)現(xiàn)類(lèi)的繼承還是有諸多繁瑣的地方的,我們需要考慮子類(lèi)和父類(lèi)的關(guān)系,繼承中的細(xì)節(jié)都需要自己手動(dòng)處理。本節(jié)我們將要學(xué)習(xí) ES6 中的類(lèi)的基本使用和類(lèi)的繼承。在學(xué)習(xí)本節(jié)我們需要明確的是,ES6 中的類(lèi)是基于現(xiàn)有語(yǔ)法的原型實(shí)現(xiàn)的,并沒(méi)有引入新的面相對(duì)象的模型。它的本質(zhì)還是我們上節(jié)提到的構(gòu)造函數(shù),只是讓我們更加方便地使用,是基于原型的繼承的語(yǔ)法糖。

2. 基本用法

2.1 語(yǔ)法

上節(jié)我們?cè)趯?shí)現(xiàn)類(lèi)的時(shí)候說(shuō),類(lèi)不能被執(zhí)行只能 new 來(lái)創(chuàng)建實(shí)例,當(dāng)時(shí)我們是在內(nèi)部手動(dòng)處理的。在 ES6 中天然支持這個(gè)特性:

class Animal { }
Animal();
// Uncaught TypeError: Class constructor Animal cannot be invoked without 'new'

上面的代碼中我們定義了一個(gè)動(dòng)物類(lèi),在控制臺(tái)中讓其執(zhí)行,會(huì)看到如上的未捕獲的類(lèi)型錯(cuò)誤:意思是在沒(méi)有 new 的情況下是無(wú)法調(diào)用構(gòu)造函數(shù) Animal 的。使用 class 定義的類(lèi)和使用構(gòu)造函數(shù)定義類(lèi),在使用上是一樣的,只是創(chuàng)建類(lèi)的方式不一樣。

上節(jié)我們知道如何創(chuàng)建實(shí)例上的屬性和原型上的屬性,那么使用 class 是怎么實(shí)現(xiàn)的呢?class 類(lèi)提供了 constructor 方法,并在 new 的時(shí)候默認(rèn)執(zhí)行,所以在 constructor 函數(shù)內(nèi)部在 this 上綁定實(shí)例上的屬性。而 原型上的方法則是在對(duì)象中直接添加屬性即可,實(shí)例如下:

class Animal {
  constructor() {
    this.type = '鳥(niǎo)類(lèi)'
  }
  eat() {}
}
var a = new Animal();
console.log(a.hasOwnProperty('type'));	// true
console.log(a.hasOwnProperty('eat'));		// false

另外,在 ES7 中 class 還提供了一種方式在實(shí)例上綁定屬性,這種方式不需要 this,直接使用等號(hào)在 class 類(lèi)中進(jìn)行賦值。

class Animal {
  constructor() {
    this.type = '鳥(niǎo)類(lèi)'
  }
  age='100'
  eat() {}
}
var a = new Animal();
console.log(a.hasOwnProperty('age'));	// true

需要注意的是,上面的等號(hào)賦值方式要在支持 ES7 的環(huán)境中才能執(zhí)行。

2.2 get/set

當(dāng)我們深入了解對(duì)象時(shí)我們就會(huì)知道屬性的 getter 和 setter ,提供了 get 和 set 兩個(gè)方法用于訪問(wèn)和設(shè)置屬性。在 ES5 中有 Object.defineProperty() 方法可以對(duì)對(duì)象的屬性進(jìn)行劫持,Vue2 的底層就是使用這個(gè) API 實(shí)現(xiàn)的。當(dāng)然 class 類(lèi)其實(shí)也是一個(gè)對(duì)象,它也可以使用 get 的方式返回屬性值。如下實(shí)例:

class Animal {
  constructor() {
    this.type = "鳥(niǎo)類(lèi)";
    this._age = 8;
  }
  get a() {
    return this._age;
  }

  set a(newValue) {
    this._age = newValue;
  }
}

var animal = new Animal();
console.log(animal.a); // 8
animal.a = 10;
console.log(animal.a); // 10

上面代碼中我們就使用了 get 和 set 去獲取屬性值和設(shè)置屬性值。那我們思考一個(gè)問(wèn)題,set 和 get 是自有屬性還是原型上的屬性呢?其實(shí) get 和 set 還是 class 類(lèi)上的一個(gè)方法,所以是原型上的方法。

console.log(a.hasOwnProperty('a'));	// false

2.3 static

ES6 提供了用于定義靜態(tài)屬性和方法的關(guān)鍵字 static ,靜態(tài)方法調(diào)用時(shí)不需要實(shí)例化該類(lèi),所以就不能通過(guò)實(shí)例去調(diào)用,但可以使用類(lèi)直接去調(diào)用。

靜態(tài)方法通常用于為一個(gè)應(yīng)用程序創(chuàng)建工具函數(shù),下面我們來(lái)看一個(gè)長(zhǎng)方形類(lèi),定義一個(gè)獲取長(zhǎng)方形面積的靜態(tài)方法。

class Rectangle {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  static getArea(r) {
    return r.width * r.height;
  }
}

const r = new Rectangle(5, 10);

console.log(Rectangle.getArea(r));	// 50

3. 繼承

3.1 extends

在上節(jié)構(gòu)造函數(shù)中的繼承我們知道,子類(lèi)的構(gòu)造函數(shù)中,需要我們?nèi)ナ謩?dòng)執(zhí)行父構(gòu)造函數(shù)并綁定this,還需要將子類(lèi)的構(gòu)造函數(shù)的原型鏈執(zhí)行父類(lèi)的原型。ES6 中的繼承非常簡(jiǎn)單,在創(chuàng)建子類(lèi)時(shí)只需要使用關(guān)鍵字 extends 即可創(chuàng)建一個(gè)子類(lèi)。

// 父類(lèi):動(dòng)物
class Animal {
  constructor(name) {
    this.name = name;
  }
  eat() {
    console.log(this.name + '會(huì)吃飯!');
  }
  static getAge() {
		console.log('獲取' + this.name + '的年齡10歲了');
		return 10;
  }
}

// 子類(lèi):具體的動(dòng)物——狗
class Dog extends Animal {}

上面的代碼中子類(lèi) Owl 繼承了 Animal,那這個(gè)時(shí)候我們都繼承了什么呢?從上面的學(xué)習(xí)中父類(lèi)中有,this 上的屬性,原型上的方法和靜態(tài)方法。

var dog = new Dog('狗');

console.log('name:', dog.name);			// name: 狗
console.log('age:', Dog.getAge());	// age: 10
dog.eat();	// 狗會(huì)吃飯!

從上面代碼打印的結(jié)果,我們知道,實(shí)例 dog 已經(jīng)繼承了 Animal 上的屬性和方法。在父類(lèi)中對(duì) eat 方法的定義不明確,所以在子類(lèi)中我們重寫(xiě) eat 方法。

class Dog extends Animal {
  eat() {
    console.log(this.name + '會(huì)吃飯!');
  }
}
var dog = new Dog('狗');
dog.eat();	// 狗喜歡吃骨頭!

3.2 super

super 是 class 中的關(guān)鍵字,可以理解是父類(lèi)的別名,用于調(diào)用對(duì)象的父對(duì)象上的函數(shù)。一般 super 有兩種情況:super 當(dāng)做函數(shù)調(diào)用;一種是 super 當(dāng)做父類(lèi)的對(duì)象使用。

第一種情況下,super 關(guān)鍵字作為函數(shù)調(diào)用,它的作用是為了綁定 this。所以子類(lèi)的構(gòu)造函數(shù)必須執(zhí)行一次 super。默認(rèn)情況下,類(lèi)中不寫(xiě) constructor 時(shí),constructor 會(huì)自動(dòng)執(zhí)行 super, 并綁定 this 指向當(dāng)前子類(lèi)。

class A {}

class B extends A {
  constructor() {
    super();
  }
}

上節(jié)中我們?cè)趧?chuàng)建子類(lèi)時(shí)就去執(zhí)行了父類(lèi)并綁定了this,上面代碼中的 super 和 A.call(this) 是相同的。

第二種情況下,super 當(dāng)作父類(lèi)的對(duì)象來(lái)使用的,什么情況下會(huì)使用呢?當(dāng)我們?cè)谧宇?lèi)中想使用父類(lèi)的方法時(shí)可以使用 super 直接調(diào)用父類(lèi)的方法即可。

class A {
  getCount() {
    return 7;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.getCount()); // 7
  }
}

let b = new B();

4. 小結(jié)

本節(jié)主要學(xué)習(xí)了 ES6 中 class 類(lèi)的使用和相關(guān)的知識(shí)點(diǎn),需要明確的是 class 類(lèi)就是一個(gè)語(yǔ)法糖,底層還是基于現(xiàn)有的原型對(duì)象的繼承來(lái)實(shí)現(xiàn)的。所以要想深入理解 ES6 的 class 就需要對(duì) ES5 中的構(gòu)造函數(shù)有深入的理解,另外,我們可以使用 babel 進(jìn)行轉(zhuǎn)譯,得到的代碼就是使用構(gòu)造函數(shù)來(lái)實(shí)現(xiàn)的。