最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Javascript Symbol原理及使用方法解析

 更新時(shí)間:2020年10月22日 08:42:08   作者:酷兒q  
這篇文章主要介紹了Javascript Symbol原理及使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

Symbol是ES6中新引入的一種基本數(shù)據(jù)類型,在此之前JavaScript中已有幾種基本數(shù)據(jù)類型:

  • Numberg
  • String
  • Boolean
  • Null
  • Undefined
  • Object

不同于其他基本類型的通俗易懂,Symbol 是什么和有什么用一直有些讓人困惑。

什么是Symbol

JavaScript標(biāo)準(zhǔn)中規(guī)定對(duì)象的key只能是 String 或 Symbol 類型,區(qū)別在于 String 類型的key可以重復(fù)而 Symbol 類型的key是唯一的。Symbol 的本質(zhì)是表示一個(gè)唯一標(biāo)識(shí)。每次創(chuàng)建一個(gè)Symbol,它所代表的值都不可能重復(fù),該值的內(nèi)部實(shí)現(xiàn)可以視為一段數(shù)字(類似:3423498431987719455..)。所以理論上 Symbol 的存在只有一個(gè)意義:用于必須使用唯一值的場(chǎng)景。

創(chuàng)建Symbol

創(chuàng)建 Number、String等基本類型的實(shí)例有兩種方法:通過(guò)構(gòu)造函數(shù)(或者叫工廠函數(shù))和文字語(yǔ)法糖。比如:

// 構(gòu)造函數(shù)
const num = Number(3);
const str = String('hi');

// 語(yǔ)法糖
const num = 3;
const str = 'hi';

顯然使用語(yǔ)法糖更加簡(jiǎn)潔。但是 Symbol 只能通過(guò)構(gòu)造函數(shù) Symbol() 進(jìn)行創(chuàng)建:

const sym = Symbol();

或者,我們可以傳入一個(gè)字符串參數(shù)(descriptor)用于描述該Symbol:

const sym = Symbol('cat');

注意:傳入的參數(shù)對(duì) Symbol 值的產(chǎn)生并無(wú)影響,因?yàn)榫退忝看蝹魅氲膮?shù)都一樣,生成的Symbol值也是不等的。該參數(shù)的作用僅用于描述被創(chuàng)建的Symbol,以便debug時(shí)可以識(shí)別出Symbol的含義。 所以,下列等式結(jié)果為 false:

Symbol('cat') === Symbol('cat') // false
Symbol.for(key)

和 Symbol() 類似,Symbol.for(key) 也可以創(chuàng)建一個(gè)Symbol,不一樣的是:創(chuàng)建的 Symbol 是全局的(在全局Symbol表中注冊(cè)),而如果全局已經(jīng)存在相同 key 的Symbol,則直接返回該Symbol。所以,下列等式結(jié)果為 true:

Symbol.for('cat') === Symbol.for('cat') // true

如何使用Symbol

其實(shí) Symbol 本身很簡(jiǎn)單,但是如何把它用好、且用的恰到好處卻使人困惑,因?yàn)樵谄匠9ぷ髦胁](méi)有多少非Symbol不用的場(chǎng)景。但是用對(duì)了Symbol會(huì)對(duì)你的代碼質(zhì)量有不少提升。來(lái)看下面幾種案例:

1. 用作對(duì)象的key,防止命名沖突

使用Symbol作為Object的key,可以保證和其他key都不重復(fù)。因此,Symbol非常適合用于對(duì)對(duì)象的屬性進(jìn)行拓展。

比如,當(dāng)使用 String 作為對(duì)象的key時(shí),一旦出現(xiàn)重復(fù)的key則后面的屬性會(huì)覆蓋前面的:

const persons = {
 'bruce': 'wayne',
 'bruce': 'banner'
}

console.log(persons.bruce); // 'wayne'
使用Symbol作為Key可以避免這種情況:

const bruce1 = Symbol('bruce');
const bruce2 = Symbol('bruce');

const persons = {
 [bruce1]: 'wayne',
 [bruce2]: 'banner'
}

console.log(persons[bruce1]); // 'wayne'
console.log(persons[bruce2]); // 'banner'

js很多內(nèi)建的方法都是通過(guò) Symbol 進(jìn)行指定的,比如:Symobol.iterator 指定了一個(gè)iterable對(duì)象的迭代器方法;Symbol.replace 指定了對(duì)象字符串替換的方法,這類 Symbol 被稱為 Well-know Symbols,代表了js語(yǔ)言的內(nèi)部行為。

2. 使用Symbol定義枚舉

由于Javascript并不自帶枚舉類型,通常情況下我們會(huì)使用一個(gè)freezed的Object來(lái)模擬枚舉類型,比如定義一個(gè)日期的枚舉:

const DAYS = Object.freeze({
monday: 1,
tuesday: 2,
wednesday: 3
});

此時(shí)有一個(gè)方法,接收 DAYS 的枚舉值來(lái)返回當(dāng)天要做的事:

function getTodo(day) {
 switch (day) {
  case DAYS.monday:
   return "看電影";
  case DAYS.tuesday:
   return "購(gòu)物";
  case DAYS.wednesday:
   return "健身";
  default:
   return "日期錯(cuò)誤";
 }
}

我們希望代碼邏輯足夠嚴(yán)謹(jǐn),傳入的參數(shù)嚴(yán)格按照 DAYS.monday 的形式,否則就返回日期錯(cuò)誤,但是該枚舉類型的實(shí)現(xiàn)卻做不到。比如:getTodo(1) 依然能得到 “看電影” 這個(gè)結(jié)果。

但是使用Symbol卻可以解決這一問(wèn)題,DAYS 枚舉類型可以重新定義為:

const DAYS = Object.freeze({
monday: Symbol('monday'),
tuesday: Symbol('tuesday'),
wednesday: Symbol('wednesday')
});

此時(shí) getTodo 方法必須接收 DAYS.monday 這樣的枚舉值作為參數(shù),否則就返回 “日期錯(cuò)誤”,因?yàn)槭澜缟显贈(zèng)]有任何一個(gè)值和 DAYS.monday 相等了。

這樣定義枚舉顯然更嚴(yán)謹(jǐn)了。

3. 使用Symbol存儲(chǔ)元數(shù)據(jù)

Key為Symbol類型的屬性是不能被枚舉的,這是 Symbol 除了唯一性外的第二大特性,因此使用for...in,Object.keys()、Object.hasOwnProperty()等方法不能識(shí)別Symbol屬性,簡(jiǎn)而言之Symbol屬性對(duì)用戶是“隱藏”的(但并不是private的,因?yàn)橛衅渌緩娇梢垣@取Symbol屬性),例如:

因此Symbol作為“隱藏”屬性可以用來(lái)存儲(chǔ)對(duì)象的元數(shù)據(jù)。比如,有一個(gè) TodoList:

class TodoList {
 constructor() {
  // todo數(shù)量
  this.count = 0;
 }

 // 增加todo
 add(id, content) {
  this[id] = content;
  this.count++;
 }
}

const list = new TodoList();

我們使用 add() 方法向其中增加幾個(gè)todo:

list.add('a', '看電影');
list.add('b', '購(gòu)物');
list.add('c', '健身');

當(dāng)我們想使用 for...in 查看里面所有的todo時(shí),會(huì)把 count 屬性也帶出來(lái):

為了隱藏count屬性,更方便的對(duì)todo進(jìn)行操作,我們可以使用Symbol來(lái)存儲(chǔ)它,TodoList 類修改為:

const count = Symbol('count');
class TodoList {
constructor() {
this[count] = 0;
}

add(id, content) {
this[id] = content;
this[count]++;
}
}

當(dāng)我們?cè)俦闅v TodoList 的時(shí)候,count就隱藏了:

當(dāng)我們想獲取存儲(chǔ)在Symbol中的原數(shù)據(jù)時(shí),可以使用 Object.getOwnPropertySymbols() 方法:

以上是我能想到的 Symbol 的用途,如果大家有其他心得體會(huì)歡迎補(bǔ)充。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • javascript巧用eval函數(shù)組裝表單輸入項(xiàng)為json對(duì)象的方法

    javascript巧用eval函數(shù)組裝表單輸入項(xiàng)為json對(duì)象的方法

    這篇文章主要介紹了javascript巧用eval函數(shù)組裝表單輸入項(xiàng)為json對(duì)象的方法,實(shí)例分析了JavaScript使用eval函數(shù)動(dòng)態(tài)構(gòu)造json對(duì)象的相關(guān)技巧,需要的朋友可以參考下
    2015-11-11
  • javascript 改變網(wǎng)頁(yè)加載的CSS

    javascript 改變網(wǎng)頁(yè)加載的CSS

    javascript 改變網(wǎng)頁(yè)加載的CSS主要通過(guò)動(dòng)態(tài)響應(yīng)select觸發(fā)的選項(xiàng)變化控制link標(biāo)簽加載的css,以實(shí)現(xiàn)不依賴cookie控制的頁(yè)面css樣式動(dòng)態(tài)加載功能,需要的朋友可以參考一下
    2007-12-12
  • 原生javascript實(shí)現(xiàn)圖片輪播效果代碼

    原生javascript實(shí)現(xiàn)圖片輪播效果代碼

    前幾天用jquery做了一個(gè)JS的圖片輪播效果,現(xiàn)在用原生的javascript代碼實(shí)現(xiàn)同樣的功能,當(dāng)練習(xí)用吧,代碼寫得不是很滿意。
    2010-09-09
  • javascript從作用域鏈談閉包

    javascript從作用域鏈談閉包

    這篇文章主要從作用域鏈談閉包,閉包(closure)是Javascript語(yǔ)言的一個(gè)難點(diǎn),也是它的特色,很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn),本文針對(duì)閉包進(jìn)行學(xué)習(xí),需要的朋友可以參考下
    2015-12-12
  • js AspxButton的客戶端操作

    js AspxButton的客戶端操作

    processOnServer使您可以指定當(dāng)前Button應(yīng)該處理客戶端的事件或服務(wù)器端事件。
    2009-06-06
  • 整理Javascript基礎(chǔ)入門學(xué)習(xí)筆記

    整理Javascript基礎(chǔ)入門學(xué)習(xí)筆記

    整理Javascript基礎(chǔ)入門學(xué)習(xí)筆記,之前一系列的文章是跟我學(xué)習(xí)Javascript,本文就是進(jìn)一步學(xué)習(xí)javascript,希望大家繼續(xù)關(guān)注
    2015-11-11
  • JS基于Mootools實(shí)現(xiàn)的個(gè)性菜單效果代碼

    JS基于Mootools實(shí)現(xiàn)的個(gè)性菜單效果代碼

    這篇文章主要介紹了JS基于Mootools實(shí)現(xiàn)的個(gè)性菜單效果代碼,涉及JavaScript頁(yè)面元素的遍歷及樣式的動(dòng)態(tài)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • JavaScript超詳細(xì)實(shí)現(xiàn)網(wǎng)頁(yè)輪播圖

    JavaScript超詳細(xì)實(shí)現(xiàn)網(wǎng)頁(yè)輪播圖

    這篇文章主要介紹了JavaScript超詳細(xì)實(shí)現(xiàn)網(wǎng)頁(yè)輪播圖,我們經(jīng)常會(huì)看到各種輪播圖的效果,它們到底是怎樣實(shí)現(xiàn)的呢?今天我們就一起來(lái)看一下具體實(shí)現(xiàn)方法吧
    2021-12-12
  • 微信小程序?qū)崿F(xiàn)多行文字滾動(dòng)效果

    微信小程序?qū)崿F(xiàn)多行文字滾動(dòng)效果

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)多行文字滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • [js高手之路]HTML標(biāo)簽解釋成DOM節(jié)點(diǎn)的實(shí)現(xiàn)方法

    [js高手之路]HTML標(biāo)簽解釋成DOM節(jié)點(diǎn)的實(shí)現(xiàn)方法

    下面小編就為大家?guī)?lái)一篇[js高手之路]HTML標(biāo)簽解釋成DOM節(jié)點(diǎn)的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08

最新評(píng)論

湘潭市| 黄石市| 西平县| 浮梁县| 墨竹工卡县| 吴忠市| 定南县| 南江县| 江津市| 武胜县| 米泉市| 新民市| 抚顺市| 巴楚县| 伊金霍洛旗| 上栗县| 松江区| 永靖县| 调兵山市| 海盐县| 铜山县| 鄂托克前旗| 交口县| 河西区| 商南县| 仁布县| 石渠县| 龙井市| 江陵县| 沽源县| 留坝县| 南宁市| 义乌市| 嵩明县| 涟水县| 托里县| 鲁山县| 博乐市| 浮山县| 蒙山县| 汾西县|