js–Symbol 符號基本數據類型
- 2021 年 10 月 24 日
- 筆記
- javascript
前言
ECMAScript 6 中新增了 Symbol 符號這一基本數據類型,那麼Symbol 是用來幹什麼的,對開發又有什麼幫助呢?本文來總結記錄一下 Symbol 的相關知識點。
正文
Symbol (符號)是 ECMAScript 6 新增的一種基本數據類型。符號是原始值,且符號實例是唯一、不可變的。符號的用途是確保對象屬性使用唯一的標識符,不會發生屬性衝突的危險,符號就是用來創建唯一記號,進而用作非字元串形式的對象屬性。
1、符號的創建
var firstSymbol = Symbol() console.log(firstSymbol); //Symbol()
上面的程式碼直接調用Symbol()方法創建了一個符號類型的變數,也可以在Symbol方法中傳入一個參數對符號變數進行描述,將來可以通過這個字元串來調試程式碼。但是,這個字元串參數與符號定義或標識完全無關。如下:
var secondSymbol = Symbol("foo") console.log(secondSymbol); //Symbol("foo") var thirdSymbol = Symbol("foo") console.log(secondSymbol == thirdSymbol); //false
Symbol 符號類型不像其他數據類型一樣可以通過 new 來創建原始值的包裝對象。若強行使用 new 會報語法錯誤。如果你確實想使用符號包裝對象,可以借用 Object() 函數。如下:
var myStr = new String("name") console.log(typeof myStr);//object // var mySymbol = new Symbol()//Symbol is not a constructor at new Symbol (<anonymous>) var mySym = Symbol() var myWrapSym = Object(mySym) console.log(typeof myWrapSym);//object
2、從全局的 Symbol 註冊表設置和取得 Symbol
var fooGlobalSymbol = Symbol.for('foo'); // 創建新符號 var otherFooGlobalSymbol = Symbol.for('foo'); // 重用已有符號 console.log(fooGlobalSymbol === otherFooGlobalSymbol); // true // 即使採用相同的符號描述,在全局註冊表中定義的符號跟使用 Symbol() 定義的符號也並不等同: var localSymbol = Symbol('foo'); var globalSymbol = Symbol.for('foo'); console.log(localSymbol === globalSymbol); // false //此外,註冊表中使用的鍵同時也會被用作符號描述。 console.log(localSymbol);//Symbol(foo) var emptyGlobalSymbol = Symbol.for(); console.log(emptyGlobalSymbol); // Symbol(undefined)
(2)Symbol.keyFor()
var s = Symbol.for('foo'); console.log(Symbol.keyFor(s)); // foo // 創建普通符號 var ss = Symbol('bar'); console.log(Symbol.keyFor(ss)); // undefined //如果傳給 Symbol.keyFor() 的不是符號,則該方法拋出 TypeError : // Symbol.keyFor(123); // TypeError: 123 is not a symbol
3、使用符號作為屬性
var s1 = Symbol("s1"); var s2 = Symbol("s2"); var s3 = Symbol("s3"); var s4 = Symbol("s4"); var obj = { [s1]: "s1 val" } console.log(obj);//{Symbol(s1): "s1 val"} Object.defineProperty(obj, s2, { value: "s2 val" }); console.log(obj);//{Symbol(s1): 's1 val', Symbol(s2): 's2 val'} Object.defineProperties(obj, { [s3]: { value: "s3 val" }, [s4]: { value: "s4 val" } }) console.log(obj);//{Symbol(s1): "s1 val",Symbol(s2): "s2 val",Symbol(s3): "s3 val",Symbol(s4):"s4 val"}
var ss1 = Symbol('foo') var info = { name: 123, age: 1232 } console.log(Object.getOwnPropertyNames(info));//['name', 'age'] Object.defineProperty(info, ss1, { value: "ss1 val" }) console.log(Object.getOwnPropertySymbols(info));//[Symbol(foo)] console.log(typeof Object.getOwnPropertySymbols(info)[0]);//'symbol' console.log(Object.getOwnPropertyDescriptors(info));//{name: {…}, age: {…}, Symbol(foo): {…}} console.log(Reflect.ownKeys(info));// ['name', 'age', Symbol(foo)] console.log(info[ss1]);//'ss1 val'
Symbol 作為屬性名,該屬性不會出現在 for…in、for…of 循環中,也不會被 Object.keys()、Object.getOwnPropertyNames()、JSON.stringify() 返回。
var person = { name: "personName", age: 18 } var sym = Symbol("sex") Object.defineProperty(person, sym, { value: "sexValue" }) for (const key in person) { console.log(key); }// name age console.log(Object.keys(person));//["name","age"]
寫在最後
以上就是本文的全部內容,希望給讀者帶來些許的幫助和進步,方便的話點個關注,小白的成長踩坑之路會持續更新一些工作中常見的問題和技術點。最後,祝各位coder,節日快樂。