// id is a new symbollet id =Symbol();// id is a symbol with the description "id" for debug purposelet id =Symbol("id");// same description but different valuelet id1 =Symbol("id");let id2 =Symbol("id");alert(id1 == id2); // false
Symbols don’t auto-convert to a string
JavaScript 大多數的值可以自動轉換成 string 但 symbol 無法自動轉換。
let id =Symbol("id");alert(id); // TypeError: Cannot convert a Symbol value to a string// convert to stringlet id =Symbol("id");alert(id.toString()); // Symbol(id), now it works// only get descriptionlet id =Symbol("id");alert(id.description); // id
“Hidden” properties
symbol 可以為物件創造隱藏的屬性,程式碼的其他部份不容易取得或改寫。
let user = { name:"John" };let id =Symbol("id");user[id] ="ID Value";alert( user[id] ); // we can access the data using the symbol as the key// useing string would be a conflict let user = { name:"John" };// our script uses "id" propertyuser.id ="ID Value";// ...if later another script the uses "id" for its purposes...user.id ="Their id value"// boom! overwritten! it did not mean to harm the colleague, but did it!
Symbols in a literal
使用 symbol 作為 key 值,要加上 [ ] 因為它是一個變數。
let id =Symbol("id");let user = { name:"John", [id]:123// not just "id: 123"};
Symbols are skipped by for…in
symbol 不算在物件迴圈內 for ( in )。
let id =Symbol("id");let user = { name:"John", age:30, [id]:123};for (let key in user) alert(key); // name, age (no symbols)// the direct access by the symbol worksalert( "Direct: "+ user[id] );// Object.assign() 會複製 symbollet id =Symbol("id");let user = { [id]:123};let clone =Object.assign({}, user);alert( clone[id] ); // 123// other type of key convert to stringlet obj = {0:"test"// same as "0": "test"};// both alerts access the same property (the number 0 is converted to string "0")alert( obj["0"] ); // testalert( obj[0] ); // test (same property)
Global symbols
symbol 通常是唯一的值,但如果想要同樣的 symbol 可以用 Symbol.for(key) 設定全域 symbol registry。
// read from the global registrylet id =Symbol.for("id"); // if the symbol did not exist, it is created// read it againlet idAgain =Symbol.for("id");// the same symbolalert( id === idAgain ); // true
Symbol.keyFor
Symbol.keyFor(sym) 返回全域 symbol 的 key名稱。
let sym =Symbol.for("name");let sym2 =Symbol.for("id");// get name from symbolalert( Symbol.keyFor(sym) ); // namealert( Symbol.keyFor(sym2) ); // id// 只能使用在全域的 symbolalert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbolalert( Symbol.keyFor(Symbol("name2")) ); // undefined, the argument isn't a global symbol