最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

【D1n910前端學(xué)習(xí)筆記】TypeScript完全解讀(3/26) Symbol

2020-01-28 17:20 作者:愛交作業(yè)的D1N910  | 我要投稿

? ? ?正常操作,正常分析,大家好,我是D1n910

之前內(nèi)容是


相比起來,這期內(nèi)容主要講的是ES6中的Symbol,其實(shí)可以理解為這個(gè)主要是用來調(diào)用一些js中內(nèi)部方法的。

TypeScript完全解讀(3/26)Symbol

typescript實(shí)現(xiàn)了ES6的Symbol

0 核心內(nèi)容

  • 基礎(chǔ)

  • 作為屬性名

  • 屬性名的遍歷

  • Symbol.for 和 Symbol.keyFor

  • 11個(gè)內(nèi)置Symbol值

0.1 準(zhǔn)備工作

1、創(chuàng)建好symbol.ts文件,路徑src/example/symbol.ts

2、之前在index.ts引入的`./example/base-type.ts`注釋掉,只引入symbol

我們可以用簡寫

1、?基礎(chǔ)

1.1、介紹

Symbol是ES6新增的一種基本數(shù)據(jù)類型,它和number、string、boolean、undefined和null等

是同一類型的,和object這種引入類型是有區(qū)別的。

Symbol用來表示獨(dú)一無二的值,獨(dú)一無二的值就代表和任何的值都不同

1.2、創(chuàng)建Symbol值

要?jiǎng)?chuàng)建Symbol類型的值,需要用Symbol的構(gòu)建函數(shù)來生成

`const s = Symbol()`

這邊我們沒有使用new來創(chuàng)建,因?yàn)镾ymbol創(chuàng)建函數(shù)會直接返回一個(gè)Symbol值。

我們可以可以打印查看創(chuàng)建的s值

我們的s是一個(gè)獨(dú)一無二的Symbol值,舉例子,創(chuàng)建s1和s2后,進(jìn)行對比

ts會提示報(bào)錯(cuò),因?yàn)樗袛嗟絪1永遠(yuǎn)不等于s2,這個(gè)等式永遠(yuǎn)為false


咱們可以給Symbol傳入?yún)?shù),這邊我們傳入的參數(shù)是d1n910,

const s3 = Symbol('d1n910')

然后打印出出來

就會發(fā)現(xiàn)打印的有的d1n910,這個(gè)是作為標(biāo)識使用。

如果我們再定義多一個(gè)同樣標(biāo)示字符串的的Symbol,

const s4 = Symbol('d1n910')

還是提示永遠(yuǎn)為false

原因就是因?yàn)槲覀兊膕ymbol就是獨(dú)一無二的,這個(gè)標(biāo)示的作用是后期打印出來讓我們看到我們這個(gè)symbol是代表什么。

這個(gè)就好比地球上,有兩個(gè)人,他們都可以取同一個(gè)名字,但是他們確實(shí)是兩個(gè)不同的人,如果我們傳入的值不是同一個(gè)字符串,而是一個(gè)數(shù)字。

那么它會在內(nèi)部調(diào)用toString()方法,轉(zhuǎn)換為字符串。

如果傳入的是對象,那么就會報(bào)錯(cuò),因?yàn)樵趖s中,這邊的Symbol()的參數(shù)只能夠傳入string類型或者number類型,

當(dāng)然,我們可以嘗試直接在瀏覽器的控制臺中看一下Symbol傳對象會有什么樣的結(jié)果

我們發(fā)現(xiàn)這邊同樣把對象運(yùn)用toString方法轉(zhuǎn)換成了字符串

Symbol值是不能用來做運(yùn)算的

但是Symbol值可以轉(zhuǎn)換為字符串和布爾類型的值

snum.toString() // 轉(zhuǎn)換為字符串

snum轉(zhuǎn)換為布爾值是true,因?yàn)樗且粋€(gè)真值

我們可以直接給它進(jìn)行取反,觸發(fā)隱式轉(zhuǎn)換打印出false值

console.log(!snum) // false?

雖然課程里沒有說到,但是這邊也試一下,那就是Symbol可以作為唯一的值進(jìn)行等式判斷,賦值以后還是代表的同一個(gè)唯一值,這真的非常美妙。


2、Symbol作為屬性名

Symbol可以作為屬性名,這里我們說一下es6新的語法

你可以用變量(或者說是表達(dá)式)傳參

你也可以用模版字符串來傳參

這樣的話就會很靈活。

我們的Symbol作為屬性名來使用時(shí),就需要用這樣的方式來進(jìn)行創(chuàng)建。

我們可以看到,它的屬性名是Symbol類型的值。

使用Symbol類型的值作為屬性名有一個(gè)好處,我們知道Symbol是獨(dú)一無二的,當(dāng)我們用Symbol作為屬性名的時(shí)候,我們就能夠保證我們的這個(gè)屬性不會被覆蓋??梢杂眠^之前的Symbol變量去引用/修改對象的值

——當(dāng)然,我們不能夠用點(diǎn)語法去修改 XD

——我們只能用方括號去獲取


3、屬性名的遍歷

這邊用Symbol作為屬性名,還有一個(gè)問題是獲取對象的屬性名時(shí)的遍歷,目前有下面這些情況是遍歷不到的。

情況一、for...in

這個(gè)會遍歷出對象的屬性名稱,在下面d1n910Obj2的屬性名稱會存儲在key中(我們往d1n910Obj2中多加了t1、t2屬性進(jìn)行觀察)

打印后發(fā)現(xiàn)沒有打印出Symbol屬性名

情況二、Object.keys()

這個(gè)的方法是會返回由傳入對象的屬性值構(gòu)建的數(shù)組,我們打印后發(fā)現(xiàn)返回的數(shù)組只包含t1、t2,不包含Symbol屬性值

情況三、Object.geyownPropertyNames()

這個(gè)方法和Object.keys()一樣,會返回由傳入對象的屬性值構(gòu)建的數(shù)組,我們打印后發(fā)現(xiàn)返回的數(shù)組只包含t1、t2,不包含Symbol屬性值

情況四、JSON.stringify()

這個(gè)方法會把傳入的對象轉(zhuǎn)換為字符串

這四種情況都是不能夠獲得Symbol屬性名的。

但是Symbol屬性在對象里不是私有屬性,我們可以用

1、Object.getOwnPropertySymbols()方法

這個(gè)方法返回了一個(gè)數(shù)組,里面包含對象里所有的Symbol類型的值。

2、Reflect.ownKeys()方法

Reflect 是新語法,為操作對象而提供的新API。

Reflect.ownKeys()這個(gè)方法返回了一個(gè)數(shù)組,里面包含對象里包括Symbol類型的屬性名

我們利用這個(gè)Symbol是唯一值,且只能夠通過變量獲取的情況,可以創(chuàng)建ES6類中的私有屬性和私有方法的效果。我們后面講類的時(shí)候,會再次講到Symbol屬性。

4、Symbol.for()?和 Symbol.keyFor()

4.1、Symbol.for()

這個(gè)方法和Symbol()一樣,可以創(chuàng)建一個(gè)Symbol值,但是他們有所不同。

我們知道,Symbol()可以創(chuàng)建兩個(gè)同樣字符串標(biāo)示的值,他們兩個(gè)是不相同的。

const s7 = Symbol('d1n910')

const s8?= Symbol('d1n910')

console.log(s7 === s8) // false

Symbol.for()在創(chuàng)建時(shí),它會這么做?

1、遍歷全局變量,如果有和傳入標(biāo)示相同標(biāo)示的Symbol值,則直接返回這個(gè)Symbol值?

2、如果沒有標(biāo)示相同的Symbol值,則在全局注冊一個(gè)新的Symbol值。

const s9?= Symbol.for('d1n910')

const s10?= Symbol.for('d1n910')

console.log(s9?=== s10) // true

* 咱們這個(gè)全局搜索,是包含了整個(gè)頁面,包括Server Worker!

4.2、Symbol.keyFor()

這個(gè)方法接收一個(gè)參數(shù),使用的是Symbol.for()方法注冊的Symbol值,他會返回Symbol.for()方法全局注冊的這個(gè)Symbol值的標(biāo)示。

* 如果不是Symbol.for創(chuàng)建的,則會返回undefined


5、11個(gè)內(nèi)置的Symbol

很少用,但是可以了解一下

5.1、Symbol.hasInstance

這個(gè)屬性指向一個(gè)內(nèi)部方法,當(dāng)你給一個(gè)對象設(shè)置以Symbol.hasInstance為屬性名的方法后,

當(dāng)其他使用instanceof來判斷一個(gè)對象是否是它的實(shí)例時(shí),就調(diào)用Symbol.hasInstance定義的方法,并且可以把調(diào)用instanceof的對象作為參數(shù)傳入。

5.2、Symbol.isConcatSpreadable

?這個(gè)用來決定數(shù)組是否會被扁平化,比如我們在用concat的時(shí)候,會把數(shù)組扁平化,如果設(shè)置Symbol.isConcatSpreadable為false,則不會被扁平化。

我們可以看到后面?zhèn)魅氲臄?shù)組被扁平化了

Symbol.isConcatSpreadable是默認(rèn)可讀寫的,所以修改之前如果我們訪問,是返回undefined,如果修改后訪問,則返回的是false(如上設(shè)置為false,當(dāng)然,你設(shè)置為true,就是true,效果和不設(shè)置為false的效果是一樣的)

5.3、Symbol.species

指定構(gòu)造衍生對象的構(gòu)造函數(shù)。

這邊我們要涉及一些類的知識。

我們先創(chuàng)建一個(gè)繼承Array的類 C。

因?yàn)槔^承,所以我們可以用原來數(shù)組定義好的方法。(這部分的內(nèi)容,我們在瀏覽器上完成)

再通過map方法創(chuàng)建c1變量,map方法是遍歷數(shù)組,然后返回由傳入函數(shù)return值組成的數(shù)組。

我們可以嘗試修改返回值看看,比如讓返回值都+1

剛剛我們的c2是通過c創(chuàng)建的,我們管c2是c衍生的數(shù)據(jù)

我們可以用instanceof判斷某個(gè)對象是不是某個(gè)類的實(shí)例。比如c是C的實(shí)例,也是C繼承的類Array的實(shí)例。

c是C構(gòu)造的實(shí)例,也相當(dāng)于是Array的實(shí)例

由c創(chuàng)建出來的衍生對象c2,也是C和Array的實(shí)例。它也能夠調(diào)用getName方法。


在ts中,如果這么寫,我們會發(fā)現(xiàn) a 是 Array構(gòu)造函數(shù)的實(shí)例,但不是C構(gòu)造函數(shù)的實(shí)例,這個(gè)和ES6是有區(qū)別的。

如果我們通過Symbol.species指定了衍生對象的構(gòu)造函數(shù),那么就會發(fā)現(xiàn)輸出結(jié)果保持一致



5.4、Symbol.match

可以對字符串的match傳入一個(gè)帶Symbol.match方法的對象,在字符串使用match方法的時(shí)候,會調(diào)用Symbol.match指向的方法,并進(jìn)行計(jì)算或者操作返回值

5.5、Symbol.replace

同上

5.6、Symbol.search

同上

5.7、Symbol.split

同上

舉例子,我們寫Symbol.split,改寫返回的內(nèi)容??


5.8、 Symbol.iterator

這個(gè)屬性用來獲得數(shù)組的遍歷器方法,通過調(diào)用這個(gè)屬性對應(yīng)的方法,可以返回一個(gè)遍歷器對象,調(diào)用next()一次,可以獲得一次當(dāng)前遍歷的對象,value代表當(dāng)前遍歷對象的值,done代表當(dāng)前遍歷是否結(jié)束。到了遍歷結(jié)束,調(diào)用next方法返回的值是{value:undefined, done:true},done為真時(shí),代表遍歷結(jié)束。

這個(gè)Symbol.iterator是可以像上面一樣改寫的,所以我們可以自定義遍歷器方法。

5.9、?Symbol.toPrimitive

指向一個(gè)方法,當(dāng)對象被轉(zhuǎn)換為原始類型值時(shí),會調(diào)用這個(gè)方法

對象進(jìn)行計(jì)算之類的情景時(shí),可能會觸發(fā)轉(zhuǎn)換為原始類型的值.

* type 說明這個(gè)對象被轉(zhuǎn)換為了那種原始類型的值

* 為了能夠在ts中執(zhí)行,所以我們這邊定義了對象類型為unknown,調(diào)用會觸發(fā)類型轉(zhuǎn)換的number方法時(shí),類型定義對象為number類型

執(zhí)行后,我們能夠在控制臺發(fā)現(xiàn)打印了一個(gè)值`number`,是因?yàn)槲覀円獔?zhí)行自增的辦法,會轉(zhuǎn)換為number類型

如果我們使用轉(zhuǎn)換為字符串的方法, 會打印 ‘default’

這個(gè)和js中是有區(qū)別的。

我們直接在瀏覽器中執(zhí)行看結(jié)果是string

5.10、?Symbol.toStringTag

和Symbol.toPrimitive相似。

可以在對象中定義為字符串或者函數(shù)方法,當(dāng)在對象上調(diào)用toString方法時(shí),就會調(diào)用以這個(gè)屬性名的方法。

我們把Symbol.toStringTag定義為字符串,調(diào)用toString方法,打印后看到和原本普通對象調(diào)用toString方法返回的"[object Object]"不一樣了,變成了"[object d1n910]"。

我們可以改寫為get方法,得到一樣的結(jié)果

5.11、?Symbol.unscopables

Symbol.unscopables能夠獲取一個(gè)對象中你不能通過with獲得的變量。

我們先看with方法是什么樣的(ts中已經(jīng)廢棄with了,所以我們在瀏覽器中使用)

with方法中,可以直接調(diào)用傳入對象里的屬性值,而不用點(diǎn)語法之類的去引用。這邊可能會造成全局創(chuàng)建變量的危險(xiǎn),所以現(xiàn)在基本上被廢棄了。

Symbol.unscopables的用法是這樣的,左邊打印的屬性代表不能夠獲得的變量

我們創(chuàng)建一個(gè)arr數(shù)組變量,發(fā)現(xiàn)不能調(diào)用findIndex方法,就是Symbol.unscopables查到在with環(huán)境中被過濾不能使的變量。

我們的indexOf能夠調(diào)用的。


本小節(jié)完畢

推薦看阮一峰老師的ES6入門書籍。

恭喜你獲得稱號

了解ES6的Symbol的勇士

你的學(xué)習(xí)進(jìn)度(3/26)

▇▇ ▇▇?▇▇?▇▇ ▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇?▇▇ ▇▇

本小節(jié)倉庫地址

https://github.com/D1N910/ts-learning/tree/master/03

?聲明

本系列內(nèi)容是D1n910通過學(xué)習(xí)Lison老師的TypeScript完全解讀(26課時(shí))整理的文字筆記,如果看完后覺得有收獲,抑或想要直接支持,抑或想要直接視頻原版內(nèi)容,請直接到https://segmentfault.com/ls/1650000018455856?r=bPXT7X。


雖然本系列是筆記,但是也有D1n910的心血所在,請勿在未告知D1n910及獲得D1n910允許的情況下直接轉(zhuǎn)載本筆記——如果您是基于筆記又生成您自己的筆記,這是一點(diǎn)問題都沒有的~

【D1n910前端學(xué)習(xí)筆記】TypeScript完全解讀(3/26) Symbol的評論 (共 條)

分享到微博請遵守國家法律
温宿县| 开化县| 武川县| 香河县| 庐江县| 德清县| 忻城县| 中方县| 安阳县| 太保市| 新乐市| 诏安县| 磐石市| 隆昌县| 于都县| 农安县| 凉城县| 济宁市| 清水河县| 安仁县| 海伦市| 临洮县| 祁阳县| 哈巴河县| 沂南县| 鄂尔多斯市| 徐水县| 申扎县| 奉化市| 永寿县| 怀来县| 健康| 麦盖提县| 宁德市| 通州区| 通道| 枣阳市| 台山市| 汉寿县| 康马县| 通渭县|