欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript面向?qū)ο笾钊肓私釫S6的class

 更新時間:2022年03月18日 10:52:55   作者:MomentYY  
class盡管只算是一個語法糖,但它卻是語言規(guī)范方面的一大成就,也對之前的繼承進行了一定的增強,下面這篇文章主要給大家介紹了關于JavaScript面向?qū)ο笾钊肓私釫S6的class的相關資料,需要的朋友可以參考下

前言

在前面一篇中主要介紹了JavaScript中使用構造函數(shù)+原型鏈實現(xiàn)繼承,從實現(xiàn)的步驟來說還是比較繁瑣的。在ES6中推出的class的關鍵字可以直接用來定義類,寫法類似與其它的面向?qū)ο笳Z言,但是使用class來定義的類其本質(zhì)上依然是構造函數(shù)+原型鏈的語法糖而已,下面就一起來全面的了解一下class吧。

1.類的定義

class關鍵字定義類可使用兩種方式來定義:

class Person {} // 類聲明
const Person = class {} // 類表達式

2.類的構造函數(shù)

從上面class定義類可以發(fā)現(xiàn)是沒有()讓我們來傳遞參數(shù)的,當希望在實例化對象的給類傳遞一些參數(shù),這個時候就可以使用到類的構造函數(shù)constructor了。

每個類都可以有一個自己的constructor方法,注意只能有一個,如果有多個會拋出異常;

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

  constructor() {}
}

當通過new操作符來操作類時,就會去調(diào)用這個類的constructor方法,并返回一個對象(具體new操作符調(diào)用函數(shù)時的默認操作步驟在上一篇中有說明);

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

const p = new Person('curry', 30)
console.log(p) // Person { name: 'curry', age: 30 }

3.類的實例方法

在構造函數(shù)中實現(xiàn)方法繼承是將其放到構造函數(shù)的原型上,而在class定義的類中,可直接在類中定義方法,最終class還是會幫我們放到其原型上,供多個實例來使用。

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

  eating() {
    console.log(this.name + 'is eating.')
  }

  running() {
    console.log(this.name + 'is running.')
  }
}

4.類的訪問器方法

在使用Object.defineProperty()方法來控制對象的屬性時,在其數(shù)據(jù)屬性描述符中可以使用setter和getter函數(shù),在class定義的類中,也是可以使用這兩個訪問器方法的。

class Person {
  constructor(name, age) {
    this.name = name
    this._age = 30 // 使用_定義的屬性表示為私有屬性,不可直接訪問
  }

  get age() {
    console.log('age被訪問')
    return this._age
  }

  set age(newValue) {
    console.log('age被設置')
    this._age = newValue
  }
}

const p = new Person('curry', 30)
console.log(p) // Person { name: 'curry', _age: 30 }
p.age // age被訪問
p.age = 24 // age被設置
console.log(p) // Person { name: 'curry', _age: 24 }

5.類的靜態(tài)方法

什么叫類的靜態(tài)方法呢?該方法不是供實例對象來使用的,而是直接加在類本身的方法,可以使用類名點出來的方法,可以使用static關鍵字來定義靜態(tài)方法。

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

  static foo() {
    console.log('我是Person類的方法')
  }
}

Person.foo() // 我是Person類的方法

6.類的繼承

6.1.extends關鍵字

在ES6之前實現(xiàn)繼承是不方便的,ES6中增加了extends關鍵字,可以方便的幫助我們實現(xiàn)類的繼承。

實現(xiàn)Student子類繼承自Person父類:

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

  eating() {
    console.log(this.name + ' is eating.')
  }
}

class Student extends Person {
  constructor(sno) {
    this.sno = sno
  }

  studying() {
    console.log(this.name + ' is studying.')
  }
}

那么子類如何使用父類的屬性和方法呢?

6.2.super關鍵字

使用super關鍵字可以在子類構造函數(shù)中調(diào)用父類的構造函數(shù),但是必須在子類構造函數(shù)中使用this或者返回默認對象之前使用super。

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

  eating() {
    console.log(this.name + ' is eating.')
  }
}

class Student extends Person {
  constructor(name, age, sno) {
    super(name, age)
    this.sno = sno
  }

  studying() {
    console.log(this.name + ' is studying.')
  }
}

const stu = new Student('curry', 30, 101111)
console.log(stu) // Student { name: 'curry', age: 30, sno: 101111 }
// 父類的方法可直接調(diào)用
stu.eating() // curry is eating.
stu.studying() // curry is studying.

但是super關鍵字的用途并不僅僅只有這個,super關鍵字一般可以在三個地方使用:

  • 子類的構造函數(shù)中(上面的用法);
  • 實例方法中:子類不僅可以重寫父類中的實例方法,還可以通過super關鍵字復用父類實例方法中的邏輯代碼;
class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }

  eating() {
    console.log(this.name + ' is eating.')
  }

  parentMethod() {
    console.log('父類邏輯代碼1')
    console.log('父類邏輯代碼2')
    console.log('父類邏輯代碼3')
  }
}

class Student extends Person {
  constructor(name, age, sno) {
    super(name, age)
    this.sno = sno
  }

  // 直接重寫父類eating方法
  eating() {
    console.log('Student is eating.')
  }

  // 重寫父類的parentMethod方法,并且復用邏輯代碼
  parentMethod() {
    // 通過super調(diào)用父類方法,實現(xiàn)復用
    super.parentMethod()

    console.log('子類邏輯代碼4')
    console.log('子類邏輯代碼5')
    console.log('子類邏輯代碼6')
  }
}

靜態(tài)方法中:用法就和實例方法的方式一樣了;

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

  static parentMethod() {
    console.log('父類邏輯代碼1')
    console.log('父類邏輯代碼2')
    console.log('父類邏輯代碼3')
  }
}

class Student extends Person {
  constructor(name, age, sno) {
    super(name, age)
    this.sno = sno
  }

  // 重寫父類的parentMethod靜態(tài)方法,并且復用邏輯代碼
  static parentMethod() {
    // 通過super調(diào)用父類靜態(tài)方法,實現(xiàn)復用
    super.parentMethod()

    console.log('子類邏輯代碼4')
    console.log('子類邏輯代碼5')
    console.log('子類邏輯代碼6')
  }
}

Student.parentMethod()

6.3.繼承內(nèi)置類

extends關鍵字不僅可以實現(xiàn)繼承我們自定義的父類,還可以繼承JavaScript提供的內(nèi)置類,可對內(nèi)置類的功能進行擴展。

比如,在Array類上擴展兩個方法,一個方法獲取指定數(shù)組的第一個元素,一個方法數(shù)組的最后一個元素:

class myArray extends Array {
  firstItem() {
    return this[0]
  }

  lastItem() {
    return this[this.length - 1]
  }
}

const arr = new myArray(1, 2, 3)
console.log(arr) // myArray(3) [ 1, 2, 3 ]
console.log(arr.firstItem()) // 1
console.log(arr.lastItem()) // 3

7.類的混入

何為類的混入?在上面的演示代碼中,都只實現(xiàn)了子類繼承自一個父類,因為JavaScript的類只支持單繼承,不能繼承自多個類。如果非要實現(xiàn)繼承自多個類呢?那么就可以引入混入(Mixin)的概念了。

看看JavaScript中通過代碼如何實現(xiàn)混入效果:

// 封裝混入Animal類的函數(shù)
function mixinClass(BaseClass) {
  // 返回一個匿名類
  return class extends BaseClass {
    running() {
      console.log('running...')
    }
  }
}

class Person {
  eating() {
    console.log('eating...')
  }
}

class Student extends Person {
  studying() {
    console.log('studying...')
  }
}

const NewStudent = mixinClass(Student)
const stu = new NewStudent
stu.running() // running...
stu.eating() // eating...
stu.studying() // studying...

混入的實現(xiàn)一般不常用,因為參數(shù)不太好傳遞,過于局限,在JavaScript中單繼承已經(jīng)足夠用了。

8.class定義類轉ES5

上面介紹ES6中類的各種使用方法,極大的方便了我們對類的使用。我們在日常開發(fā)中編寫的ES6代碼都是會被babel解析成ES5代碼,為了對低版本瀏覽器做適配。那么使用ES6編寫的類被編譯成ES5語法會是什么樣呢?通過babel官網(wǎng)的試一試可以清楚的看到ES6語法轉成ES5后的樣子。

  • 剛開始通過執(zhí)行自調(diào)用函數(shù)得到一個Person構造函數(shù);
  • 定義的實例方法和類方法會分別收集到一個數(shù)組中,便于后面直接調(diào)用函數(shù)進行遍歷添加;
  • 判斷方法類型:如果是實例方法就添加到Person原型上,是類方法直接添加到Person上;
  • 所以class定義類的本質(zhì)還是通過構造函數(shù)+原型鏈,class就是一種語法糖;

這里可以提出一個小問題:定義在constructor外的屬性最終會被添加到哪里呢?還是會被添加到類的實例化對象上,因為ES6對這樣定義的屬性進行了單獨的處理。

class Person {
  message = 'hello world'

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

  eating() {
    console.log(this.name + ' is eating.')
  }

  static personMethod() {
    console.log('personMethod')
  }
}

const p = new Person('curry', 30)
console.log(p) // Person { message: 'hello world', name: 'curry', age: 30 }

擴展:在上圖中通過通過babel轉換后的代碼中,定義的Person函數(shù)前有一個/*#__PURE__*/,那么這個有什么作用呢?

  • 實際上這個符號將函數(shù)標記為了純函數(shù),在JavaScript中純函數(shù)的特點就是沒有副作用,不依賴于其它東西,獨立性很強;
  • 在使用webpack構建的項目中,通過babel轉換后的語法更有利于webpack進行tree-shaking,沒有使用到的純函數(shù)會直接在打包的時候被壓縮掉,達到減小包體積效果;

總結

到此這篇關于JavaScript面向?qū)ο笾钊肓私釫S6的class的文章就介紹到這了,更多相關了解ES6的class內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論