ES6中的Symbol

来源:https://www.cnblogs.com/noobakong/archive/2018/11/13/9954897.html
-Advertisement-
Play Games

恢復內容開始 1. Symbol 1.1 概述 保證每個屬性的名字都是獨一無二的就好了,這樣就從根本上防止屬性名的衝突。這就是 ES6 引入Symbol的原因 在es6之前,JavaScript數據類型分為 Number、Boolean、String、Null、Undefined、Object es ...


---恢復內容開始---

  1. Symbol

1.1 概述

保證每個屬性的名字都是獨一無二的就好了,這樣就從根本上防止屬性名的衝突。這就是 ES6 引入Symbol的原因

在es6之前,JavaScript數據類型分為

Number、Boolean、String、Null、Undefined、Object

es6中,新增了一個基本數據類型 Symbol

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

Symbol值是由Symbol函數調用產生的

對象的屬性名現在可以有兩種類型,一種是原來就有的字元串,另一種就是新增的 Symbol 類型。凡是屬性名屬於 Symbol 類型,就都是獨一無二的,可以保證不會與其他屬性名產生衝突。

let s = Symbol();

typeof s
// "symbol"

Symbol 函數不是構造函數,不能通過new 來構造一個Symbol實例,因為Symbol生成的是一個原始類型值,而不是對象。

Symbol函數可以接受一個字元串作為參數,表示對 Symbol 實例的描述,主要是為了在控制台顯示,或者轉為字元串時,比較容易區分。

let s1 = Symbol('foo');
let s2 = Symbol('bar');

s1 // Symbol(foo)
s2 // Symbol(bar)

s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"

每一個Symbol都是獨一無二的

// 沒有參數的情況
let s1 = Symbol();
let s2 = Symbol();

s1 === s2 // false

// 有參數的情況
let s1 = Symbol('foo');
let s2 = Symbol('foo');

s1 === s2 // false

另外,Symbol 值也可以轉為布爾值,Symbol 值不能與其他類型的值進行運算,會報錯。

1.2 作為屬性名的Symbol

由於每一個 Symbol 值都是不相等的,這意味著 Symbol 值可以作為標識符,用於對象的屬性名,就能保證不會出現同名的屬性。這對於一個對象由多個模塊構成的情況非常有用,能防止某一個鍵被不小心改寫或覆蓋。

let mySymbol = Symbol();

// 第一種寫法
let a = {};
a[mySymbol] = 'Hello!';

// 第二種寫法
let a = {
  [mySymbol]: 'Hello!'
};

// 第三種寫法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上寫法都得到同樣結果
a[mySymbol] // "Hello!"

Symbol 值作為對象屬性名時,不能用點運算符,使用 Symbol 值定義屬性時,Symbol 值必須放在方括弧之中。

1.3 應用實例

屬性私有化 - 數據保護

場景:我們想創建一個構造函數Person,我們希望Person的性別在被創建後,就保存到死,無法改變。

這個時候我們就可以使用我們的Symbol作為Person屬性名:

var Person = (function() {
    let _gender = Symbol('gender');
    function P(name, gender) {
        this.name = name;
        this[_gender] = gender;
    }
    return P;
  })();

var p1 = new Person('阿孔', '男');
console.log(p1);

上述代碼很簡單,我們使用Symbol函數創建一個Symbol值作為我們構造函數Person的一個屬性,性別。

可以看到,我們的Symbol性別屬性被添加到實例當中

此時如果我們想通過常規的方法來取我們的屬性值,

console.log(p1[Symbol('gender')])

我們預期的可能是能取到 “男”,但是取到的是undefined

這說明,我們此時的Symbol屬性外部只能看,不能讀,更不能改。大大的加強了屬性的私有化屬性。

但是我們可以在構造函數內部來獲取使用我們的值

在構造函數內部,我們可以在原型鏈上添加一個say方法

P.prototype.say = function() {
    console.log(this[_gender]);
}
...

  p1.say()

打開控制台,我們就可以看到 男 被列印了出來。

1.4 Symbol.for(),Symbol.keyFor()

Symbol.for()

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

有時,我們希望重新使用同一個 Symbol 值,Symbol.for方法可以做到這一點。它接受一個字元串作為參數,然後搜索有沒有以該參數作為名稱的 Symbol 值。如果有,就返回這個 Symbol 值,否則就新建並返回一個以該字元串為名稱的 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。

1.5 內置的 Symbol 值

除了定義自己使用的 Symbol 值以外,ES6 還提供了 11 個內置的 Symbol 值,指向語言內部使用的方法。

Symbol目前最常用的地方就是作為對象的私有屬性去,更多更高級的內容可以訪問 http://es6.ruanyifeng.com/#docs/symbol

---恢復內容結束---


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 最近公司要在APP上添加一個人臉識別功能,在網上搜了一圈,發現虹軟的人臉識別SDK挺好用的,而且還免費,所以就下載了他們的SDK研究了一下。總的來看功能挺好用的,只是demo上面部分功能不是很完善,所以就在官方demo的基礎上改動了一些小的功能。 新增功能:1. 通過圖片註冊人臉2. 增加列表頁面可 ...
  • 歡迎大家前往 "騰訊雲+社區" ,獲取更多騰訊海量技術實踐乾貨哦~ 本文由 "goo" 發表於 "雲+社區專欄" 相信我們對Android系統都不陌生,而Android系統博大精深,被各種各樣的智能設備承載的同時,我們會否好奇過,如此複雜的Android究竟是怎麼運作起來的呢?借本文給大家分享,筆者 ...
  • 222
    11 ...
  • 在嘗試使用webRTC實現webapp直播失敗後,轉移思路開始另外尋找可行的解決方案。在網頁上嘗試使用webRTC實現視頻的直播與看直播,在谷歌瀏覽器以及safari瀏覽器上測試是可行的。但是基於基座打包為webapp後不行,所以直播的話建議還是原生的好。HBuilder自帶的H5+有提供了原生的視 ...
  • 很久沒寫總結了,在這裡跟大家分享一下自己踩的坑,同時也方便自己多記憶下。 大致流程: 使用create-react-app腳手架生成react相關部分,腳手架內部會通過node自動起一個客戶端,然後和普通的ajax請求一樣,和遠端伺服器進行通信,只不過這裡採用支持rpc通信的grpc-web來發起請 ...
  • 開發者的javascript造詣取決於對【動態】和【非同步】這兩個詞的理解水平。 一. 概述 1.1 MVVM模型 模型是前端單頁面應用中非常重要的模型之一,也是 的底層思想,如果你也因為自己學習的速度拼不過開發框架版本迭代的速度,或許也應該從更高的抽象層次去理解現代前端開發,因為其實最核心的經典思想 ...
  • isPrototypeOf 作用:檢測一個對象是否是另一個對象的原型。或者說一個對象是否被包含在另一個對象的原型鏈中 instanceof instanceof運算符希望左操作數是一個對象,右操作數標識對象的類。如果左側對象是右側類的實例,則表達式返回為true,否則返回false。 hasOwnP ...
  • 題外話.......最近在開發一個網站項目的時候,需要用到網頁自定義右鍵菜單,在網上看了各路前輩大神的操作,頭暈目眩,為了達到目的,突然靈機一動,於是便有了這篇文章. 先放個效果圖(沾沾自喜,大神勿噴): 廢話不多說,進入正題: 1.首先 我們要禁用掉原網頁中右鍵菜單 這樣目標區域的右鍵菜單就無法使 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...