国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【ES6】更易于繼承的類語法

Lionad-Morotar / 554人閱讀

摘要:的類使用熟悉的關鍵字指定類繼承的函數,并且可以通過方法訪問父類的構造函數。例如繼承一個的類繼承了,術語上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實例,也是派生類的實例,內建對象繼承的實用之處是改變返回對象的類型。

和其它面向對象編程語言一樣,ES6 正式定義了 class 類以及 extend 繼承語法糖,并且支持靜態、派生、抽象、迭代、單例等,而且根據 ES6 的新特性衍生出很多有趣的用法。
一、類的基本定義

基本所有面向對象的語言都支持類的封裝與繼承,那什么是類?

類是面向對象程序設計的基礎,包含數據封裝、數據操作以及傳遞消息的函數。類的實例稱為對象。

ES5 之前通過函數來模擬類的實現如下:

// 構造函數
function Person(name) {
  this.name = name;
}
// 原型上的方法
Person.prototype.sayName = function(){
  console.log(this.name);
};
// new 一個實例
var friend = new Person("Jenny");

friend.sayName(); // Jenny
console.log(friend instanceof Person);   // true
console.log(friend instanceof Object);   // true

總結來說,定義一個類的思路如下

1.需要構造函數封裝數據

2.在原型上添加方法操作數據,

3.通過New創建實例

ES6 使用class關鍵字定義一個類,這個類有特殊的方法名[[Construct]]定義構造函數,在 new 創建實例時調用的就是[[Construct]],示例如下:

/*ES6*/
// 等價于 let Person = class {
class Person {
  // 構造函數
  constructor(name) {
    this.name = name;
  }
  // 等價于Person.prototype.sayName
  sayName() {
    console.log(this.name);
  }
}

console.log(typeof Person);   // function
console.log(typeof Person.prototype.sayName);   // function

let friend = new Person("Jenny");

friend.sayName(); // Jenny
console.log(friend instanceof Person);   // true
console.log(friend instanceof Object);   // true

上面的例子中class定義的類與自定義的函數模擬類功能上貌似沒什么不同,但本質上還有很大差異的:

函數聲明可以被提升,但是class類聲明與let類似,不能被提升;

類聲明自動運行在嚴格模式下,“use strict”;

類中所有方法都是不可枚舉的,enumerable 為 false。

二、更靈活的類

類和函數一樣,是JavaScript的一等公民(可以傳入函數、從函數返回、賦值),并且注意到類與對象字面量還有更多相似之處,這些特點可以擴展出類更靈活的定義與使用。

2.1 擁有訪問器屬性

對象的屬性有數據屬性和訪問屬性,類中也可以通過getset關鍵字定義訪問器屬性:

class Person {
  constructor(name) {
    this.name = name;
  }

  get value () {
    return this.name + this.age
  }
  set value (num) {
    this.age = num
  }
}

let friend = new Person("Jenny");
// 調用的是 setter
friend.value = 18
// 調用的是 getter
console.log(friend.value) // Jenny18
2.2 可計算的成員名稱

類似 ES6 對象字面量擴展的可計算屬性名稱,類也可以用[表達式]定義可計算成員名稱,包括類中的方法和訪問器屬性:

let methodName = "sayName"

class Person {
  constructor(name) {
    this.name = name;
  }

  [methodName + "Default"]() {
    console.log(this.name);
  }

  get [methodName]() {
    return this.name
  }

  set [methodName](str) {
    this.name = str
  }
}

let friend = new Person("Jenny");

// 方法
friend.sayNameDefault(); // Jenny
// 訪問器屬性
friend.sayName = "lee"
console.log(friend.sayName) // lee
想進一步熟悉對象新特性可參考:【ES6】對象的新功能與解構賦值
2.3 定義默認迭代器

ES6 中常用的集合對象(數組、Set/Map集合)和字符串都是可迭代對象,如果類是用來表示值這些可迭代對象的,那么定義一個默認迭代器會更有用。

ES6 通過給Symbol.iterator屬性添加生成器的方式,定義默認迭代器:

class Person {
  constructor(name) {
    this.name = name;
  }

  *[Symbol.iterator]() {
    for (let item of this.name){
      yield item
    }
  }
}

var abbrName = new Person(new Set(["j", "j", "e", "e", "n", "y", "y", "y",]))
for (let x of abbrName) {
  console.log(x); // j e n y
}
console.log(...abbrName) // j e n y

定義默認迭代器后類的實例就可以使用for-of循環和展開運算符(...)等迭代功能。

對以上迭代器內容感到困惑的可參考:【ES6】迭代器與可迭代對象
2.4 作為參數的類

類作為"一等公民”可以當參數使用傳入函數中,當然也可以從函數中返回:

function createClass(className, val) {
  return new className(val)
}

let person = createClass(Person,"Jenny")
console.log(person) // Person { name: "Jenny" }
console.log(typeof person) // object
2.5 創建單例

使用類語法創建單例的方式通過new立即調用類表達式

let singleton = new class {
  constructor(name) {
    this.name = name;
  }
}("Jenny")
 
console.log(singleton.name) // Jenny

這里先創建匿名類表達式,然后 new 調用這個類表達式,并通過小括號立即執行,這種類語法創建的單例不會在作用域中暴露類的引用。

三、類的繼承

回顧 ES6 之前如何實現繼承?常用方式是通過原型鏈、構造函數以及組合繼承等方式。

ES6 的類使用熟悉的extends關鍵字指定類繼承的函數,并且可以通過surpe()方法訪問父類的構造函數

例如繼承一個 Person 的類:

class Friend extends Person {
  constructor(name, phone){
    super(name)
    this.phone = phone
  }
}

let myfriend = new Friend("lee",2233)
console.log(myfriend) // Friend { name: "lee", phone: 2233 }

Friend 繼承了 Person,術語上稱 Person 為基類,Friend 為派生類

需要注意的是,surpe()只能在派生類中使用,它負責初始化 this,所以派生類使用 this 之前一定要用surpe()

3.1 繼承內建對象

ES6 的類繼承可以繼承內建對象(Array、Set、Map 等),繼承后可以擁有基類的所有內建功能。例如:

class MyArray extends Array {
}

let arr = new MyArray(1, 2, 3, 4),
  subarr = arr.slice(1, 3)

console.log(arr.length) // 4
console.log(arr instanceof MyArray) // true
console.log(arr instanceof Array) // true
console.log(subarr instanceof MyArray) // true

注意到上例中,不僅 arr 是派生類 MyArray 的實例,subarr 也是派生類 MyArray 的實例,內建對象繼承的實用之處是改變返回對象的類型

瀏覽器引擎背后是通過[Symbol.species]屬性實現這一行為,它被用于返回函數的靜態訪問器屬性,內建對象定義了[Symbol.species]屬性的有 Array、ArrayBuffer、Set、Map、Promise、RegExp、Typed arrays。
3.2 繼承表達式的類

目前extends可以繼承類和內建對象,但更強大的功能從表達式導出類!

這個表達式要求可以被解析為函數并具有[[Construct]]屬性和原型,示例如下:

function Sup(val) {
  this.value = val
}

Sup.prototype.getVal = function () {
  return "hello" + this.value
}

class Derived extends Sup {
  constructor(val) {
    super(val)
  }
}

let der = new Derived("world")
console.log(der) // Derived { value: "world" }
console.log(der.getVal()) // helloworld
3.3 只能繼承的抽象類

ES6 引入new.target元屬性判斷函數是否通過new關鍵字調用。類的構造函數也可以通過new.target確定類是如何被調用的。

可以通過new.target創建抽象類(不能實例化的類),例如:

class Abstract  {
  constructor(){
    if(new.target === Abstract) {
      throw new Error("抽象類(不能直接實例化)")
    }
  }
}

class Instantiable extends Abstract {
  constructor() {
    super()
  }
}

// let abs = new Abstract() // Error: 抽象類(不能直接實例化)
 let abs = new Instantiable()
console.log(abs instanceof Abstract) // true

雖然不能直接使用 Abstract 抽象類創建實例,但是可以作為基類派生其它類。

四、類的靜態成員

ES6 使用static關鍵字聲明靜態成員或方法。在類的方法或訪問器屬性前都可以使用static,唯一的限制是不能用于構造函數。

靜態成員的作用是某些類成員的私有化,及不可在實例中訪問,必須要直接在類上訪問。

class Person {
  constructor(name) {
    this.name = name;
  }

  static create(name) {
    return new Person(name);
  }
}

let beauty = Person.create("Jenny");
// beauty.create("lee") // TypeError

如果基類有靜態成員,那這些靜態成員在派生類也可以使用。

例如將上例的 Person 作為基類,派生出 Friend 類并使用基類的靜態方法create( ):

class Friend extends Person {
  constructor(name){
    super(name)
  }
}

var friend = Friend.create("lee")
console.log(friend instanceof Person) // true
console.log(friend instanceof Friend) // false

可以看出派生類依然可以使用基類的靜態方法。

推薦閱讀《深入理解ES6》

加油哦少年!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98979.html

相關文章

  • es6 - 類

    摘要:創建自定義類型看下面一段代碼上面代碼使用創建了一個自定義類型,是這個類的構造器,是類的公共方法。注意事項在使用類繼承的實現中,需要注意的點是如果子類沒有重寫方法,默認會調用父類的構造器方法。 es6 類-class 與大多正規的面向對象編程語言不同(比如java),js在創建之初就不支持類。js的面向對象編程實現方式是通過構造函數和原型來實現的。 我之前以為es6引入類的概念將會帶給這...

    notebin 評論0 收藏0
  • ES6—class與面向對象編程(8)

    摘要:接下來我們看下類的寫法,這個就很接近于傳統面向對象語言了。如果你想了解傳統面向對象語言,這里是一個好切入點。作為對象時,指向父類的原型對象。這些就是為將來在中支持面向對象的類機制而預留的。 在ES5中,我們經常使用方法或者對象去模擬類的使用,并基于原型實現繼承,雖然可以實現功能,但是代碼并不優雅,很多人還是傾向于用 class 來組織代碼,很多類庫、框架創造了自己的 API 來實現 c...

    wangjuntytl 評論0 收藏0
  • JavaScript 中的類繼承

    摘要:因為操作符創建的對象都繼承自構造函數的屬性。繼承的實現中常用的繼承方式是組合繼承,也就是通過構造函數和原型鏈繼承同時來模擬繼承的實現。 原文發布在我的博客 我們都知道 JavaScript 是一門基于原型的語言。當我們調用一個對象本身沒有的屬性時,JavaScript 就會從對象的原型對象上去找該屬性,如果原型上也沒有該屬性,那就去找原型的原型,一直找原型鏈的末端也就是 Object....

    rottengeek 評論0 收藏0
  • es6之js的類

    摘要:生成的類的原型會被自動調整,而你還能調用方法來訪問基類的構造器。唯一能避免調用的辦法,是從類構造器中返回一個對象。 起源 JS 從創建之初就不支持類,也沒有把類繼承作為定義相似對象以及關聯對象的主要方式,這讓不少開發者感到困惑。而從 ES1 誕生之前直到ES5 時期,很多庫都創建了一些工具,讓 JS 顯得貌似能支持類。盡管一些 JS 開發者強烈認為這門語言不需要類,但為處理類而創建的代...

    libin19890520 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<