Symbol


概述

ES5的對象屬性名都是字符串,這容易造成屬性名的沖突。比如,你使用了一個他人提供的對象,但又想為這個對象添加新的方法(mixin模式),新方法的名字就有可能與現有方法產生沖突。如果有一種機制,保證每個屬性的名字都是獨一無二的就好了,這樣就從根本上防止屬性名的沖突。這就是ES6引入Symbol的原因。

ES6引入了一種新的原始數據類型Symbol,表示獨一無二的值。它是JavaScript語言的第七種數據類型,前六種是:Undefined、Null、布爾值(Boolean)、字符串(String)、數值(Number)、對象(Object)。

Symbol值通過Symbol函數生成。這就是說,對象的屬性名現在可以有兩種類型,一種是原來就有的字符串,另一種就是新增的Symbol類型。凡是屬性名屬於Symbol類型,就都是獨一無二的,可以保證不會與其他屬性名產生沖突。

Symbol的特性就是唯一性

Symbol(符號)是一種新的基本類型值

基本使用

Symbol的使用就是直接圓括號調用,不能通過new來構造

基本使用

 

 Symbol內部可以傳入參數,參數的作用是對這個符合的描述

let a = Symbol('hello')
console.log(a);

 

 Symbol的唯一性

Symbol是代表唯一的意思,同值的Symbol是不相等的

let a = Symbol()
let b = Symbol()
console.log(a == b); 

 

 即使內部傳入參數相同也不相等

let a = Symbol('hello')
let b = Symbol('hello')
console.log(a == b); 

 

 Symbol的內部參數

(1)Symbol內部如果是字符串表示當前這個符合的描述信息

let a = Symbol('hello')
console.log(a)

(2)Symbol內部如果是對象,並且有toString方法,返回的就是這個符合的描述

let a = Symbol({
  a: 100,
  toString: function() {
      return "symbol的描述信息"
  }
})
console.log(a);

 

(3)Symbol內部如果是數組,內部的參數會被扁平化,用逗號隔開

let a = Symbol([
    1,
    2,
    'a',
    'b'
])
console.log(a);

 

 Symbol的應用場景

Symbol可以來創建對象的內部屬性,內部屬性的特點是防止外部獲取或者隨意篡改

let sym = Symbol("objKey")
let obj = {
    a: 1,
    b: 2,
    c: 3,
    [sym]: 1
}
obj.c = 2;
console.log(obj);

 

symbol定義的屬性,外部是無法獲取的,因為我們知道symbol同值是不相等的。所以下面的途徑是獲取不到的

obj[Symbol("objKey")]

上面的結果會返回undefined,因為symbol("objKey") != symbol("objKey")

 並且對象遍歷symbol的時候是得不到這個key的

let sym = Symbol("objKey")
let obj = {
    a: 1,
    b: 2,
    c: 3,
    [sym]: 300
}

for (let item in obj) {
    console.log(item);
}

 使用Object.keys方法也不能獲取symbol對應的key

let sym = Symbol("objKey")
let obj = {
    a: 1,
    b: 2,
    c: 3,
    [sym]: 300
}

console.log(Object.keys(obj));

 

 獲取對象中Symbol的key的方法

 第一個方法是Object.getOwnPropertySymbols,返回的是只有symbol定義的key

let sym = Symbol("objKey")
let obj = {
    a: 1,
    b: 2,
    c: 3,
    [sym]: 10
}
let result = Object.getOwnPropertySymbols(obj)
console.log(result)

第二個方法是Reflect.ownKeys,返回的是所有的key,包含symbol定義的key

let sym = Symbol("objKey")
let obj = {
    a: 1,
    b: 2,
    c: 3,
    [sym]: 10
}
let result = Reflect.ownKeys(obj)
console.log(result)

 

 這兩種方法還是可以獲取對象中symbol對應的值的

let sym = Symbol("objKey")
let obj = {
    a: 1,
    b: 2,
    c: 3,
    [sym]: 10
}
let result = obj[Object.getOwnPropertySymbols(obj)[0]]
console.log(result)

 

 共享符號

上面注冊的都是普通符號,也可以注冊共享符號

 普通符號:

let a = Symbol()

共享符號:

let a = Symbol.for()

.for()就代表創建了一個共享的符號,內部參數也是描述信息

let str = Symbol.for("b");
let str2 = Symbol.for("b");
console.log(str == str2); 

 

 上面的結果返回的是true,機理是:Symbol.for()定義的符號代表共享符號,如果創建了共享符號,此時就相當於在全局創建了一個符號,此時如果再次創建相同描述的符號,就不會再創建新的了,而是將原來的拋出,所以結果是相等的。

 Symbol.keyFor方法

來獲取已經注冊到全局的共享符號的描述信息

let str = Symbol.for("b");
console.log(Symbol.keyFor(str));

 

 Symbol的注意事項

Symbol值不能與其他類型的值進行運算,會報錯:

var str = Symbol('小明');
console.log("我是"+str)

 

 Symbol值可以顯式轉為字符串:

var str = Symbol('小明');
let str2=String(str)
let str3=str.toString()
console.log(typeof str2)
console.log(typeof str3)

 

 Symbol值也可以轉為布爾值,但是不能轉為數值

var num = Symbol(2);
let num2=Boolean(num);
console.log(typeof num2)

 

 此時改為數值就回報錯

var num = Symbol(2);
let num2=Number(num);
console.log(typeof num2)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM