Symbol ES6 【7】大數據類型

原始數據類型

  1. undefined
  2. null
  3. 布爾值(Boolean)
  4. 字符串(String)
  5. 數值(Number)
  6. Symbol

引用數據類型

  1. 對象(Object)

Symbol

ES6 引入了一種新的原始數據類型Symbol,表示獨一無二的值。

創建方式

  1. Symbol()
  2. Symbol(參數)

注意

  • Symbol函數前不能使用new命令,否則會報錯。這是因爲生成的 Symbol 是一個原始類型的值,不是對象。也就是說,由於 Symbol 值不是對象,所以不能添加屬性。基本上,它是一種類似於字符串的數據類型。
  • Symbol函數可以接受一個字符串作爲參數,表示對 Symbol 實例的描述,主要是爲了在控制檯顯示,或者轉爲字符串時,比較容易區分

由來

ES5 對象屬性名 都是 字符串 容易造成屬性名的 衝突

var obj = { info:'Hello' };

obj.info = 'World';

console.log(obj.info); # World
console.log(obj['info']); # World

可見info屬性被重寫

凡是屬性名屬於 Symbol 類型,就都是獨一無二的,可以保證不會與其他屬性名產生衝突。

Symbol() === Symbol()  # false

Symbol('info') === Symbol('info')  # false

應用

注意

  • Symbol 值不能與其他類型的值進行運算,會報錯。
let sym = Symbol('My symbol');

"your symbol is " + sym
// TypeError: can't convert symbol to string
`your symbol is ${sym}`
// TypeError: can't convert symbol to string
  1. 作爲屬性名的Symbol
let sym = Symbol('My symbol');

let obj = {};
obj.name = 'Hello';
obj[sym] = 'World';
console.log(obj); # { name: 'Hello', [Symbol(My symbol)]: 'World' }
  • Symbol值作爲對象屬性名時,不能用點運算符。
let name = Symbol('My symbol');

let obj = {};
obj.name = 'Hello';
obj[name] = 'World';
console.log(obj); # { name: 'Hello', [Symbol(My symbol)]: 'World' }

console.log(obj.name); # Hello
console.log(obj[name]); # World

console.log(Object.keys(obj)); # [ 'name' ]
console.log(Object.getOwnPropertyNames(obj)); # [ 'name' ]
console.log(Object.getOwnPropertySymbols(obj)); # [ Symbol(My symbol) ]
  • 可以看到Object.keys()和Object.getOwnPropertyNames()無法獲取到Symbol屬性
  • 可以通過Object.getOwnPropertySymbols()方法獲取Symbol屬性

Reflect.ownKeys

新的 API,Reflect.ownKeys()方法可以返回所有類型的鍵名,包括常規鍵名和 Symbol 鍵名。

for(let key of  Reflect.ownKeys(obj)){
    console.log(key,obj[key]);
}

# name Hello
# Symbol(My symbol) World
  • 通過鍵名我們可以獲取到Symbol爲屬性名對應的屬性值

Symbol.for()

Symbol.for()與Symbol()這兩種寫法,都會生成新的 Symbol。
它們的區別是,前者會被登記在全局環境中供搜索,後者不會。
Symbol.for()不會每次調用就返回一個新的 Symbol 類型的值,而是會先檢查給定的key是否已經存在,如果不存在纔會新建一個值。
比如,如果你調用Symbol.for(“cat”)30 次,每次都會返回同一個 Symbol 值,但是調用Symbol(“cat”)30 次,會返回 30 個不同的 Symbol 值。

Symbol.for("bar") === Symbol.for("bar")
// true

Symbol("bar") === Symbol("bar")
// false
  • 由於Symbol()寫法沒有登記機制,所以每次調用都會返回一個不同的值。
  • Symbol.for()爲 Symbol 值登記的名字,是全局環境的,不管有沒有在全局環境運行。
function foo() {
  return Symbol.for('bar');
}

const x = foo();
const y = Symbol.for('bar');
console.log(x === y); // true
  • Symbol.for(‘bar’)是函數內部運行的,但是生成的 Symbol 值是登記在全局環境的。所以,第二次運行Symbol.for(‘bar’)可以取到這個 Symbol 值。

Symbol.keyFor()

Symbol.keyFor()方法返回一個已登記的 Symbol 類型值的key。

let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"

let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined
  • 變量s2屬於未登記的 Symbol 值,所以返回undefined。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章