亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

ES6 更易于繼承的類語法的使用

2024-05-06 16:48:03
字體:
來源:轉載
供稿:網友

和其它面向對象編程語言一樣,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(); // Jennyconsole.log(friend instanceof Person);  // trueconsole.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);  // functionconsole.log(typeof Person.prototype.sayName);  // functionlet friend = new Person("Jenny");friend.sayName(); // Jennyconsole.log(friend instanceof Person);  // trueconsole.log(friend instanceof Object);  // true

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

  • 函數聲明可以被提升,但是class類聲明與let類似,不能被提升;
  • 類聲明自動運行在嚴格模式下,“use strict”;
  • 類中所有方法都是不可枚舉的,enumerable 為 false。

二、更靈活的類

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

2.1 擁有訪問器屬性

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

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");// 調用的是 setterfriend.value = 18// 調用的是 getterconsole.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) // 4console.log(arr instanceof MyArray) // trueconsole.log(arr instanceof Array) // trueconsole.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) // trueconsole.log(friend instanceof Friend) // false

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
在线观看视频99| 日韩中文有码在线视频| 久久久亚洲影院你懂的| 热久久这里只有精品| 欧美专区在线视频| 国产精品成人品| 色综合老司机第九色激情| 久久久免费精品视频| 国产精品爱久久久久久久| 欧美成人免费va影院高清| 欧美乱妇高清无乱码| 国产精品成熟老女人| 日本不卡免费高清视频| 欧洲亚洲在线视频| 亚洲最新av在线网站| 久久成人精品一区二区三区| 91免费福利视频| 国产精品视频一区二区三区四| 中文字幕日韩免费视频| 中文字幕日韩欧美在线| 日韩精品小视频| 国产精品精品久久久| 国产成人精品一区二区| 成人黄色影片在线| 亚洲综合自拍一区| 国产精品aaaa| 日本中文字幕不卡免费| 精品偷拍一区二区三区在线看| 欧美不卡视频一区发布| 日韩免费在线播放| 色偷偷偷综合中文字幕;dd| xxx欧美精品| 超碰91人人草人人干| 欧美一级淫片播放口| 日韩在线观看免费av| 久久成人av网站| 2021国产精品视频| 欧美激情久久久久| 午夜精品久久久久久久99热| 国产精品91在线观看| 久久精品99国产精品酒店日本| 欧美成人精品激情在线观看| 性欧美视频videos6一9| 日本久久久a级免费| 欧美xxxwww| 一区二区亚洲精品国产| 色综合久久久888| 久久亚洲综合国产精品99麻豆精品福利| 亚洲欧美日韩一区二区三区在线| 日韩在线播放av| 国产精品自拍偷拍| 色黄久久久久久| 欧美另类老肥妇| 欧美高清在线视频观看不卡| 日韩在线一区二区三区免费视频| www.欧美免费| 午夜精品久久久久久久99黑人| 成人精品一区二区三区| 亚洲第一视频在线观看| 亚洲无av在线中文字幕| 精品亚洲国产视频| 亚洲男人天堂2024| 久久成人亚洲精品| 全亚洲最色的网站在线观看| 91免费视频国产| 久久久久久久av| 亚洲男人第一av网站| 亚洲性69xxxbbb| 中文字幕免费精品一区| 狠狠躁夜夜躁久久躁别揉| 久久久久www| 亚洲精品一区二三区不卡| 亚洲人成伊人成综合网久久久| 国自在线精品视频| 日韩电影在线观看永久视频免费网站| 成人97在线观看视频| 在线电影av不卡网址| 人九九综合九九宗合| 久久色免费在线视频| 欧美大片免费看| 国产精品成人国产乱一区| 成人av在线亚洲| 欧美性猛交xxxx免费看| 国产精品免费视频久久久| 午夜精品久久久久久久99黑人| 这里只有精品丝袜| 亚洲最大福利视频网| 国产精品久久久久久久久免费看| 日韩午夜在线视频| 欧美视频免费在线观看| 久久69精品久久久久久久电影好| 黄色一区二区三区| 欧美极品第一页| 中文字幕久久精品| 久久久国产一区二区| 91精品国产免费久久久久久| 国产一区二区三区免费视频| 最近2019年手机中文字幕| 欧美激情视频在线观看| 久久精品国产亚洲| 国产精品香蕉av| 精品视频一区在线视频| 亚洲欧美日韩精品久久亚洲区| 91久久久久久久一区二区| 91精品啪aⅴ在线观看国产| 不卡av在线播放| 成人福利网站在线观看| 欧美视频裸体精品| 精品久久中文字幕久久av| 欧美电影院免费观看| 91久久精品视频| 98精品国产高清在线xxxx天堂| 国产精品欧美在线| 日韩成人在线视频观看| 亚洲人免费视频| 秋霞av国产精品一区| 欧美性猛交xxxx免费看漫画| 欧美成人三级视频网站| 国产91精品久久久久久| 成人免费高清完整版在线观看| 亚洲美女激情视频| 欧美高清视频在线观看| 欧美成人亚洲成人日韩成人| 第一福利永久视频精品| 久久综合久中文字幕青草| 国产成人精品免高潮在线观看| 国产香蕉97碰碰久久人人| 国产成人精品电影久久久| 欧美韩日一区二区| 日韩精品在线免费观看| 亚洲国产成人av在线| 97免费中文视频在线观看| 欧美综合在线观看| 亚洲精品videossex少妇| 在线观看欧美www| 久久精品99久久香蕉国产色戒| 中文字幕亚洲色图| 欧美高清自拍一区| 大桥未久av一区二区三区| 久久久免费av| 国产精品日韩精品| 亚洲欧洲美洲在线综合| 中文字幕亚洲图片| 亚洲国产精品福利| 蜜臀久久99精品久久久久久宅男| 日韩中文在线中文网在线观看| 久操成人在线视频| 精品色蜜蜜精品视频在线观看| 国产精品视频免费在线观看| 欧美激情2020午夜免费观看| 成人激情视频在线观看| 91久久久久久久久久| 在线亚洲午夜片av大片| 久久综合国产精品台湾中文娱乐网| 欧美日韩在线影院| 日本久久久久久久| 成人乱人伦精品视频在线观看| 国外成人在线视频| 亚洲欧美日韩国产中文| 插插插亚洲综合网| 日韩暖暖在线视频| 国产区亚洲区欧美区| 亚洲精品国精品久久99热| 国产精品一二三在线|