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

JavaScript原始數(shù)據(jù)類型Symbol的用法詳解

 更新時間:2022年11月08日 14:24:33   作者:亦世凡華、  
Symbol是ES6中引入的一種新的基本數(shù)據(jù)類型,用于表示一個獨一無二的值。它是JavaScript中的第七種數(shù)據(jù)類型。本文將詳細講講Symbol的使用,需要的可以參考一下

Symbol介紹與創(chuàng)建

ES6引入了一種新的原始數(shù)據(jù)類型Symbol,表示獨一無二的值,它是JavaScript語言的第七種數(shù)據(jù)類型,是一種類似于字符串的數(shù)據(jù)類型。

Symbol特點:

Symbol的值是唯一的,用來解決命名沖突問題。

Symbol值不能與其他數(shù)據(jù)進行運算。

Symbol定義的對象屬性不能使用 for...in 循環(huán)遍歷,但是可以使用 Reflect.ownKeys 來獲取對象的所有鍵名。

Symbol值通過Symbol()函數(shù)生成,也就是說,對象的屬性名可以有兩種類型,一種就是原來就有的字符串,另一種就是新增的Symbol類型。

創(chuàng)建Symbol有倆種方式,Symbol和Symbol.for(),這兩種方式的區(qū)別前者不能登記在全局環(huán)境中供搜索,后者卻可以,所有Symbol.for()不會每次調(diào)用就返回一個新的Symbol類型值,而是先檢查給定的key值是否存在,不存在才會新建一個值。

<script>
    // 創(chuàng)建Symbol
    let s = Symbol()
    console.log(s,typeof s);//Symbol() 'symbol'
    //Symbol()函數(shù)可以接受一個字符串作為參數(shù),表示對 Symbol 實例的描述
    //Symbol()函數(shù)的參數(shù)只是表示對當(dāng)前 Symbol 值的描述,因此相同參數(shù)的Symbol函數(shù)的返回值是不相等的。
    let s1 = Symbol('張三')
    let s2 = Symbol('張三')
    console.log(s1 === s2);//false
    // 創(chuàng)建Symbol的另一種方法:Symbol.for() 該方法創(chuàng)建的字符串參數(shù)相等,Symbol也相等
    let s3 = Symbol.for('張三')
    let s4 = Symbol.for('張三')
    // Symbol.keyFor()方法返回一個已登記的 Symbol 類型值的key。
    console.log(Symbol.keyFor(s3));//張三
    console.log(s3 === s4);//true
</script>

Symbol 值不能與其他類型的值進行運算,否則會報錯,但是Symbol值可以顯示轉(zhuǎn)換為字符串,而且Symbol也可以轉(zhuǎn)為布爾值。

<script>
    let s = Symbol('My Symbol')
    // let result = s + 100
    // console.log(result);//Cannot convert a Symbol value to a number
    // 轉(zhuǎn)字符串
    console.log(String(s));//Symbol(My Symbol)
    // 轉(zhuǎn)布爾值
    console.log(Boolean(s));//true
</script>

當(dāng)然如果你想直接返回 Symbol 的字符串參數(shù)的值的話,可以借用 Symbol 的實例屬性:description,直接返回 Symbol 值的描述。

<script>
    let s = Symbol('My Symbol')
    console.log(s.description);//My Symbol
</script>

針對數(shù)據(jù)類型的類別可以總結(jié)以下方式:(面試官問你JS有哪幾種數(shù)據(jù)類型好用到)

USONB (you are so niubility)

u:undefined

s:string、Symbol

o:object

n:null、number

b:boolean

設(shè)置Symbol屬性的注意點

為了保證不會出現(xiàn)同名的屬性,防止對象的某一個鍵不小心被改寫或覆蓋。使用作為屬性名的Symbol 進行操作。設(shè)置Symbol的方式如下:

注意:我們在進行設(shè)置Symbol值作為對象屬性名時,是不能用點運算符,因為點運算符后面總是字符串,所以不會讀取作為Symbol標識名所指代的那個值,導(dǎo)致Symbol的屬性名實際上是一個字符串,而不是一個Symbol值,所以在對象內(nèi)部使用Symbol值定義屬性時,Symbol值必須放在方括號里面。

<script>
    let s = Symbol('My Symbol')
    // 第一種
    let a = {}
    a[s] = 'hello world'
    // 第二種
    let b = {
        [s]:'hello people'
    }
    // 第三種
    let c = {}
    Object.defineProperty(c,s,{value:'hello animal'})
    // 以上結(jié)果都能達到相同的效果,舉例
    console.log(c);
</script>

Symbol屬性名的遍歷

如果想遍歷Symbol的屬性名,正常的方法是辦不到的,需要使用特定的方法,有一個方法可以獲取指定對象的所有鍵名并返回一個數(shù)組,方法為:Object.getOwnPropertySymbols()方法。

<script>
    let obj = {}
    let a = Symbol('a')
    let b = Symbol('b')
    obj[a] = 'hello'
    obj[b] = 'world'
    const objectSymbols = Object.getOwnPropertySymbols(obj)
    console.log(objectSymbols);//[Symbol(a), Symbol(b)]
</script>

上面的方法能夠返回Symbol的鍵名,還有一個方法能夠返回Symbol鍵名,但不只有Symbol鍵名而是所有的鍵名都被返回出來。該方法為:Reflect.ownKeys(obj)。

<script>
    let obj = {
        name:'張三',
        age:18,
        [Symbol('mySymbol')]:1,
        gender:'男'
    }
    console.log(Reflect.ownKeys(obj));//['name', 'age', 'gender', Symbol(mySymbol)]
</script>

Symbol內(nèi)置值

除了定義自己使用的 Symbol 值以外,ES6還提供了 11 個內(nèi)置的 Symbol 值,指向語言內(nèi)部使用的方法。方法如下:

Symbol.hasInstance

當(dāng)其他對象使用 instanceof 運算符,判斷是否為該對象的實例時,會調(diào)用這個方法。

<script>
    class Person {
        static [Symbol.hasInstance](param){
            console.log(param);
            console.log('我被用來檢測類型了');
            //return true
        }
    }
    let o = {}
    console.log(o instanceof Person);
</script>

當(dāng)出現(xiàn) instanceof 時,symbol 的 hasInstance 屬性就會被觸發(fā),并且可以把要判斷的實例對象傳進來。也就是說將 instanceof 前面的值傳遞到 param 形參這個方法,由它來決定返回的true還是false。說白了就是可以自己控制類型檢測。

Symbol.isConcatSpreadable

對象的 Symbol.isConcatSpreadable 屬性等于的是一個布爾值,表示該對象用于數(shù)組上面時Array.prototype.concat()語句,判斷數(shù)組是否可以展開。false為不展開。

<script>
    const arr = [1,2,3]
    const arr1 = [4,5,6]
    console.log(arr.concat(arr1));
    // 將arr1設(shè)置為不展開,作為一個整體與arr進行合并
    arr1[Symbol.isConcatSpreadable] = false
    console.log(arr.concat(arr1));
</script>

類似數(shù)組的對象正好相反,默認不展開,它的 Symbol.isConcatSpreadable 屬性設(shè)為 true,才能展開。

<script>
    let obj = {
        0:'a',
        1:'b',
        2:'c',
        length:3
    }
    console.log([1,2].concat(obj,'d'));
    // 將該屬性設(shè)置為true,進行展開
    obj[Symbol.isConcatSpreadable] = true
    console.log([1,2].concat(obj,'d'));
</script>

Symbol.unscopables

該對象指定了使用 with 關(guān)鍵字時,哪些屬性會被 with 環(huán)境排除。

<script>
    // 將排除的鍵名以數(shù)組方式打印出來
    console.log(Object.keys(Array.prototype[Symbol.unscopables]));
</script>

// 沒有 unscopables 時
class MyClass {
  foo() { return 1; }
}
var foo = function () { return 2; };
 
with (MyClass.prototype) {
  foo(); // 1
}
// 有 unscopables 時
// 通過指定Symbol.unscopables屬性,使得with語法塊不會在當(dāng)前作用域?qū)ふ襢oo屬性,即foo將指向外層作用域的變量
class MyClass {
  foo() { return 1; }
  get [Symbol.unscopables]() {
    return { foo: true };
  }
}
var foo = function () { return 2; };
with (MyClass.prototype) {
  foo(); // 2
}

Symbol.match

JavaScript中的Symbol.match屬性是well-known符號,用于標識正則表達式與字符串的匹配,當(dāng)執(zhí)行 str.match(myObject) 時,如果該屬性存在,會調(diào)用它,返回該方法的返回值。

<script>
    const reg = /hello world/
    reg[Symbol.match] = false
    console.log('/hello/'.startsWith(reg));//false
    console.log('/hello world/'.startsWith(reg));//true
</script>

Symbol.replace

當(dāng)該對象被 str.replace(myObject) 方法調(diào)用時,會返回該方法的返回值。

<script>
    const x = {};
    // Symbol.replace方法會收到兩個參數(shù),第一個參數(shù)是replace方法正在作用的對象,第二個參數(shù)是替換后的值。
    x[Symbol.replace] = (...s) => console.log(s); // ["Hello", "World"]
    'Hello'.replace(x, 'World')
</script>

Symbol.search

指定了一個搜索方法,這個方法接受用戶輸入的正則表達式,返回該正則表達式在字符串中匹配到的下標,這個方法由以下的方法來調(diào)用 String.prototype.search()。該屬性指向一個方法,當(dāng)該對象被 str.search(myObject)方法調(diào)用時,會返回該方法的返回值。

<script>
    class caseInsensitiveSearch {
    constructor(value) {
        this.value = value.toLowerCase();
    }
    [Symbol.search](string) {
        return string.toLowerCase().indexOf(this.value);
    }
    }
    console.log('foobar'.search(new caseInsensitiveSearch('BaR')));
    // expected output: 3
</script>

Symbol.split

Symbol.split 這個屬性方法 指向的是一個正則表達式的索引處分割字符串的方法,這個方法通過 String.prototype.split() 調(diào)用;該屬性指向一個方法,當(dāng)該對象被 str.split(myObject)方法調(diào)用時,會返回該方法的返回值。

<script>
    var exp =  {
        pat:'in',
        [Symbol.split](str) {
        return str.split(this.pat);
        }
    }
    // "dayinlove".split(exp)調(diào)用[Symbol.split](str)處理,并把實參"dayinlove"傳給形參str
    console.log("dayinlove".split(exp));//["day", "love"]
</script>

Symbol.iterator

對象進行 for...of 循環(huán)時,會調(diào)用 Symbol.iterator 方法,返回該對象的默認遍歷器。

<script>
    const myIterable = {};
    myIterable[Symbol.iterator] = function* () { //function*這種聲明方式會定義一個生成器函數(shù),它返回一個對象。
        yield 1;
        yield 2;
        yield 3;
    };
    console.log([...myIterable]);// [1, 2, 3]
</script>

Symbol.toPrimitive

作為對象的函數(shù)值屬性存在的,當(dāng)一個對象轉(zhuǎn)換為對應(yīng)的原始值時,會調(diào)用此函數(shù)。該函數(shù)被調(diào)用時,會傳遞一個字符粗參數(shù) hint ,表示要轉(zhuǎn)換到的原始值的預(yù)期類型。hint參數(shù)的取值是:number、string 和 default 中的任意一個。

// 一個沒有提供 Symbol.toPrimitive 屬性的對象,參與運算時的輸出結(jié)果
var obj1 = {};
console.log(+obj1);     // NaN
console.log(`${obj1}`); // "[object Object]"
console.log(obj1 + ""); // "[object Object]"
// 接下面聲明一個對象,手動賦予了 Symbol.toPrimitive 屬性,再來查看輸出結(jié)果
var obj2 = {
  [Symbol.toPrimitive](hint) {
    if (hint == "number") {
      return 10;
    }
    if (hint == "string") {
      return "hello";
    }
    return true;
  }
};
console.log(+obj2);     // 10      -- hint 參數(shù)值是 "number"
console.log(`${obj2}`); // "hello" -- hint 參數(shù)值是 "string"
console.log(obj2 + ""); // "true"  -- hint 參數(shù)值是 "default"

Symbol.toStringTag

通常作為對象的屬性鍵使用,對應(yīng)的屬性值應(yīng)該為字符串類型,這個字符串用來表示該對象的自定義類型標簽。

<script>
    class Person {
        get [Symbol.toStringTag](){
            return 'xxx'
        }
    }
    let per = new Person()
    console.log(Object.prototype.toString.call(per));//[object xxx]
</script>

Symbol.species

指定構(gòu)造函數(shù)用于創(chuàng)建派生對象的函數(shù)值屬性,即創(chuàng)建衍生對象時,會使用該屬性。作用:實例對象在運行過程中,會調(diào)用該屬性指定的構(gòu)造函數(shù),用來返回基類的實例而不是子類的實例。

<script>
    class Array1 extends Array {
        static get [Symbol.species]() { return Array; }
    }
    const a = new Array1(1, 2, 3);
    const mapped = a.map(x => x * x);
    // 定義了Symbol.species屬性后,導(dǎo)致 a.map(x => x * x) 生成的衍生對象不在是Array1的實例而是Array
    console.log(mapped instanceof Array1);//false
    console.log(mapped instanceof Array);//true
</script>

到此這篇關(guān)于JavaScript原始數(shù)據(jù)類型Symbol的用法詳解的文章就介紹到這了,更多相關(guān)JS Symbol內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript中省略元素對數(shù)組長度的影響

    JavaScript中省略元素對數(shù)組長度的影響

    這篇文章主要介紹了JavaScript中省略元素對數(shù)組長度的影響,本文給大家介紹的非常詳細具有參考借鑒價值,需要的朋友可以參考下
    2016-10-10
  • js文本框輸入點回車觸發(fā)確定兼容IE、FF等

    js文本框輸入點回車觸發(fā)確定兼容IE、FF等

    js文本框輸入點回車觸發(fā)確定兼容IE、FF等,下面有個不錯的示例,感興趣的朋友可以參考下
    2013-11-11
  • JavaScript中new操作符的原理示例詳解

    JavaScript中new操作符的原理示例詳解

    javascript中的new是一個語法糖,new的過程實際上是創(chuàng)建一個新對象,把新象的原型設(shè)置為構(gòu)造器函數(shù)的原型,這篇文章主要給大家介紹了關(guān)于JavaScript中new操作符原理的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • Javascript?、Vue禁止鼠標右鍵點擊事件實例

    Javascript?、Vue禁止鼠標右鍵點擊事件實例

    這篇文章主要給大家介紹了關(guān)于Javascript?、Vue禁止鼠標右鍵點擊事件的相關(guān)資料,禁止右鍵的原理是通過JavaScript阻止瀏覽器右鍵事件的默認行為,從而達到禁止右鍵的效果,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • js實現(xiàn)簡單的打印表格

    js實現(xiàn)簡單的打印表格

    這篇文章主要為大家詳細介紹了js實現(xiàn)簡單的打印表格,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • JavaScript插入排序算法原理與實現(xiàn)方法示例

    JavaScript插入排序算法原理與實現(xiàn)方法示例

    這篇文章主要介紹了JavaScript插入排序算法原理與實現(xiàn)方法,簡單分析了插入排序的概念、原理并結(jié)合實例形式分析了JavaScript插入排序算法的具體實現(xiàn)技巧與注意事項,需要的朋友可以參考下
    2018-08-08
  • 詳解小程序緩存插件(mrc)

    詳解小程序緩存插件(mrc)

    這篇文章主要介紹了詳解小程序緩存插件(mrc),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • JavaScript setTimeout使用閉包功能實現(xiàn)定時打印數(shù)值

    JavaScript setTimeout使用閉包功能實現(xiàn)定時打印數(shù)值

    這篇文章主要介紹了JavaScript setTimeout使用閉包功能實現(xiàn)定時打印數(shù)值 的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • innerHTML,outerHTML,innerTEXT三者之間的區(qū)別

    innerHTML,outerHTML,innerTEXT三者之間的區(qū)別

    innerHTML,outerHTML,innerTEXT三者之間的區(qū)別...
    2007-01-01
  • JavaScript this關(guān)鍵字的深入詳解

    JavaScript this關(guān)鍵字的深入詳解

    這篇文章主要給大家介紹了關(guān)于JavaScript this關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01

最新評論