深入理解ES6 006【學習筆記】

Symbol和Symbol屬性

6種原始數據類型:Symbol。私有名稱原本是為了讓開發者們創建非字符串屬性名稱而設計的,但是一般的技術無法檢測這些屬性的私有名稱

創建Symbol

let firstName = Symbol();
let person = {}
person[firstName] = "Nicholas";
console.log(person[firstName]); // Nicholas 

new Symbol() 會報錯,Symbol函數接受一個可選參數,其可以讓你添加一段文本描述即將創建的Symbol,這段描述不可用於屬性訪問,但是建議你在每次創建Symbol時都添加一段描述,以便於閱讀代碼和調試Symbol程序

let firstName = Symbol('first name');
let person = {}
person[firstName] = "Nicholas"
console.log("first name" in person); // false
console.log(person[firstName]); //Nicholas
console.log(firstName) // "Symbol(first name)"

Symbol的描述被存儲在內部的[[Description]]屬性中,只有當調用Symbol的toString()方法才可以讀取這個屬性,在執行console.log時,隱式調用了firstName的toString()方法,所以它的描述會被打印到日誌中,但是不能直接在代碼里訪問[[Description]]

使用typeof symbol 如果是會返回'symbol',所有使用計算屬性名的地方,都可以使用Symbol。

Symbol的使用方法

我們之前都是在括號中使用Symbol,事實上,Symbol也可以用於可計算對象字面量屬性、Object.defineProperty()方法和Object.defineProperties()方法的調用過程

let fristName = Symbol("first name");
// 使用一個可計算對象這字面量屬性
let person = {
  [firstName]:"Nicholas"
}
// 將屬性設置為只讀
Object.defineProperty(person,firstName,{writable:false})

let lastName = Symbol('last name');

Object.defineProperties(person,{
  [lastName]:{
    value:"Zakas",
    writable:false
  }
})
console.log(person[firstName]) //Nicholas
console.log(person[lastName]) //Zakas

雖然在所有使用可計算屬性名的地方,都可以使用Symbol來替代,但是為了在不同的代碼片段間有效地共享這些Symbol,需要建立一個體系

Symbol共享體系

例如我們想在不同的對象類型,想使用同一個Symbol屬性來表示一個獨特的標識符。在很大的代碼庫或跨文件追蹤Symbol非常困難且容易出錯,出於這些原因ES6提供了一個可以隨時訪問全局Symbol註冊表。使用Symbol.for(xxx) 只接受一個參數。要創建Symbol的字符串描述類似Symbol('xxx')Symbol.for(xxx)會去全局註冊表中找有沒有註冊這個Symbol,有就返回,沒有就創建一個並註冊到全局表中,下次不用再新建一個了。

Symbol與類型轉換

我上面的示例使用console.log()方法來輸出Symbol的內容,它會調用Symbol的String()方法輸出有用信息,如果你試圖將一個Symbol和一個字符串拼接,會導致程序拋出錯誤。

let uid = Symbol.for("uid"),
desc = String(uid);
console.log(desc); // Symbol(uid)

Symbol的屬性檢索

Object.keys()Object.getOwnPropertyNames()方法可以檢索對象中所有的屬性名,後一個方法不考慮屬性的可枚舉性一律返回。這兩個方法都支持Symbol屬性。所以又推出了一個Object.getOwnPropertySymbols()方法返回一個包含所有Symbole自有屬性的值。

let uid = Symbol.for("uid");
let object = {
  [uid]:"12345"
}
let symbols = Object.getOwnPropertySymbols(object);
console.log(symbols.length) // 1
console.log(symbols[0]) // "Symbol(uid)"
console.log(object[symbols[0]]) //12345

通過well-know Symbol暴露內部操作

  • Symbol.hasInstance
  • Symbol.isConcatSpreadable
  • Symbol.iterator
  • Symbol.match
  • Symbol.replace
  • Symbol.species
  • Symbol.split
  • Symbol.species
  • Symbol.toPrimitive
  • Symbol.toStringTag
  • Symbol.unscopables
obj instanceof Array;
// 等價於
Array[Symbol.hasInstance](obj)
// 本質上,es6只是將instanceof操作符重新定義為此方法的簡寫語法,現在引入調用後,就可以隨意改變instanceof的運行方式了。
// 假設你想定義一個無實例的函數,就可以將Symbol.hasInstance的返回值硬編碼為false
function MyObject(){
  // 空函數
}
Object.defindProperty(MyObject,Symbol.hasInstance,{
  value:function(v){
    return false
  }
})
let obj = new MyObject()
console.log(obj instanceof MyObject) // false

Symbol.isConcatSpreadable

js數組的concat方法被設計用於拼接兩個數組,使用如下方法:

let color1 =["red","green"],
color2 = color1.concat(["blue","black"])
console.log(color2.length) // 4
console.log(color2) // ["red","green","blue","black"]

// color1與一個臨時數組拼接成兩個數組
// concat方法也可以接受非數組參數,此時該方法只會將這些參數逐一添加到數組末尾如下
let color1 =["red","green"],
color2 = color1.concat(["blue","black"],"brown")
console.log(color2.length) // 5
console.log(color2) // ["red","green","blue","black","brown"]
// 這個屬性可以設置或阻止調用concat方法時是否展開

主題測試文章,只做測試使用。發佈者:Walker,轉轉請注明出處:https://walker-learn.xyz/archives/4332

(0)
Walker的頭像Walker
上一篇 2026年3月10日 00:00
下一篇 2026年3月8日 15:40

相關推薦

  • TS珠峰 004【學習筆記】

    類型體操 type-1 // 內置 // Partial Required Readonly 修飾類型的 // Pick Omit 處理數據結構 // Exclude Extract 處理集合類型的 // Paramters RetrunValue infer // 字符串類型,模板字符串`${}` + infer PartialPropsOptional …

    個人 2025年3月27日
    1.4K00
  • 深入理解ES6 004【學習筆記】

    擴展對象的功能 普通對象 具有js對象所有默認內部行為的 特異對象 具有某些與默認行為不符的內部行為 標準對象 es6規範中定義的對象,Array/Date等 內建對象 腳本開始執行時存在於javascript執行環境的對象,所有標準對象都是內建對象 對象字面量語法擴展 屬性初始值的簡寫,當一個對象的屬性與本地變量同名時,不必再寫冒號和值 對象方法的簡寫語法…

    個人 2025年3月8日
    1.3K00
  • Go工程師體系課 008【學習筆記】

    訂單及購物車 先從庫存服務中將 srv 的服務代碼框架複製過來,查找替換對應的名稱(order_srv) 加密技術基礎 對稱加密(Symmetric Encryption) 原理: 使用同一個密鑰進行加密和解密 就像一把鑰匙,既能鎖門也能開門 加密速度快,適合大量數據傳輸 使用場景: 本地文件加密 數據庫內容加密 大量數據傳輸時的內容加密 內部系統間的快速通…

    個人 2025年11月25日
    26400
  • Nuxt3_掃盲 入門與原理介紹【學習筆記】

    Nuxt 3 入門與原理介紹 💡 甚麼是 Nuxt 3? Nuxt 3 是基於 Vue 3 和 Vite 打造的全棧前端框架,支持: 服務端渲染(SSR) 靜態站點生成(SSG) 單頁應用(SPA) 構建全棧應用(支持 API) Nuxt 3 是 Vue 的“加強版”,幫你簡化項目結構和開發流程。 🔧 核心原理 功能 Nuxt 如何處理 ✅ 頁面路由 自動根…

    個人 2025年4月6日
    2.2K00
  • Go工程師體系課 protobuf_guide【學習筆記】

    Protocol Buffers 入門指南 1. 簡介 Protocol Buffers(簡稱 protobuf)是 Google 開發的一種語言無關、平台無關、可擴展的結構化數據序列化機制。與 JSON、XML 等序列化方式相比,protobuf 更小、更快、更簡單。 項目主頁:https://github.com/protocolbuffers/prot…

    個人 2025年11月25日
    1.3K00
簡體中文 繁體中文 English