【面試題】JS第七種數據類型Symbol詳解

来源:https://www.cnblogs.com/mochenxiya/archive/2022/09/08/16668516.html
-Advertisement-
Play Games

JS第七種數據類型Symbol詳解 點擊打開視頻講解更加詳細 一、什麼是Symbol? Symbol是ES6中引入的一種新的基本數據類型,用於表示一個獨一無二的值。它是JavaScript中的第 七種數據類型,與undefined、null、Number(數值)、String(字元串)、Boolea ...


JS第七種數據類型Symbol詳解

點擊打開視頻講解更加詳細

一、什麼是Symbol?

Symbol是ES6中引入的一種新的基本數據類型,用於表示一個獨一無二的值。它是JavaScript中的第
七種數據類型,與undefined、null、Number(數值)、String(字元串)、Boolean(布爾值)、
Object(對象)併列。

Symbol特點:

  • Symbol的值是唯一的,用來解決命名衝突問題
  • Symbol值不能與其他數據進行運算
  • Symbol定義的對象屬性不能使用for...in迴圈遍歷,但是可以使用Reflect.ownKeys來獲取對象的所有鍵名

基本用法:

let a = Symbol("末晨曦吖");
console.log(a); // Symbol(末晨曦吖)
console.log(typeof a); //symbol

// 相同參數 Symbol() 返回的值不相等
let b = Symbol("末晨曦吖");
console.log(a === b); //false

為什麼相同參數 Symbol() 返回的值不相等???

因為使用Symbol()創建一個Symbol類型的值並賦值給a變數後,你就得到了一個在記憶體中獨一無二的值。現在除了通過變數a,任何人在任何作用域內都無法重新創建出這個值。所以就算我們通過相同參數創建的b,結果還是不相等的。

儘管a和b都是使用Symbol()創建出來的,但是它們在記憶體中看起來卻是這樣的:

11111111111111111.png

實際上,a變數拿到了記憶體中某塊記憶體的唯一引用(這裡所說的引用,其實就是該記憶體的地址)。如果不藉助a變數,你不可能再得到這個地址。因此:

a !== b;  //a和b持有的是兩塊記憶體的引用
 
const c = a;  //手動把a里保存的地址保存在c變數中
a === c;  //c和a現在指向同一塊記憶體,因為它們保存了同樣的地址

222222222222222.png

這種行為看似難以理解,但其實它與對象遵循相同的規則,如:

let a = {};
let b = {};
 
a !== b;  //a和b各自被分配了不同的記憶體,因此它們保存了不同的地址
 
//藉助變數a,變數c拿到了a指向的那個對象的地址,因此兩者相等
let c = a;
a === c;

但是對於同為基本數據類型的字元串來說,它不遵循類似的規則。比如:

let a = "123";
let b = "123";
 
a === b;  //返回true。兩者在常量區引用同一個字元串

3333333333333.png

我們首先通過變數a在記憶體中創建了字元串“123”,然後在不藉助變數a的情況下,又通過var b = "123"拿到了對“123”這個字元串的引用,兩者指向記憶體中的同一塊記憶體地址。

因此我們說,a無法確保別的變數無法拿到它保存的地址(前提是不通過a)。但是對於var a = Symbol()這樣的語句,a變數內保存的值是唯一的,因為除了藉助a變數,你永遠無法得到a中保存的值。這也是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值作為對象屬性名時,不能用點運算符。

let a = {};
let name = Symbol();
a.name = 'lili';
a[name] = 'lucy';
console.log(a.name,a[name]);//lili,lucy
Symbol值作為屬性名時,該屬性還是公開屬性,不是私有屬性。

二、Symbol中的方法

1、Symbol.for()

我們知道Symbo()創建的兩個變數永遠不會是相同的。那麼如果我們需要重新使用同一個Symbol怎麼辦,總不能需要挨個去進行比較吧。還好,es6為我們提供了Symbol.for()方法。 

參數是symbol類型的描述信息,不同於Symbol(),這個而參數只能是字元串或者是undefined,若已經創建了則返回這個symbol,否則就進行創建並將這個新的symbol返回,代碼如下

let name = Symbol.for("末晨曦");
let name1 = Symbol.for("末晨曦");
console.log(name === name1);  // true

請註意,我們在使用創建描述信息為"末晨曦"的變數的時候,使用的是for,而不是Symbol(),倘若使用Symbol()進行首次創建,for會再次創建一次,二者不會相等,代碼如下:

let name = Symbol("末晨曦");
let name1 = Symbol.for("末晨曦");
console.log(name === name1);  // false

原因在於Symbol.for()會有一個登記機制,使用for只會對通過for創建的symbol進行檢查,不會對Symbol()創建的進行檢查。

2、Symbol.keyFor()

這個方法參數是一個通過Symbol.for()創建的symbol類型變數,返回這個symbol變數的描述信息。

let name = Symbol.for("末晨曦");
console.log(Symbol.keyFor(name)); // "末晨曦"
let name1 = Symbol("末晨曦");
console.log(Symbol.keyFor(name1)); // undefined 不能查找Symbol()創建的變數

若對您有幫助,請點擊跳轉B站一鍵三連哦!感謝支持!!!


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

-Advertisement-
Play Games
更多相關文章
  • 1. 參考https://ask.dcloud.net.cn/article/36937: 增加如下參考條款 我們的產品基於DCloud uni-app(5+ App/Wap2App)開發,應用運行期間需要收集您的設備唯一識別碼(IMEI/android ID/DEVICE_ID/IDFA、SIM ...
  • 華為開發者聯盟和艾瑞咨詢聯合發佈《2022年移動應用技術趨勢白皮書》,本白皮書通過盤點國內移動應用發展環境、熱門技術創新動態,分析影響移動應用發展的技術趨勢,以及細分應用領域的技術創新熱點,洞悉開發者所面臨的挑戰和機遇,幫助開發者釐清不斷發展的技術局面,提供可落地的行業洞察。 華為開發者聯盟一直致力 ...
  • Math對象 Math對象,不是一個構造函數,所以我們不需要new 來調用,而是直接使用裡面的屬性和方法即可,它具有數學常數和函數的方法,跟數學相關的運算(求絕對值,取整,最大值等)可以使用Math中的成員。 1.Math絕對值和三個取整的方法: 2.Math隨機數方法 Math對象隨機數方法:ra ...
  • 每日3題 28 以下代碼執行後,控制臺中的輸出內容為? function showCase(value){ switch(value){ case 'A': console.log('case A'); break; case 'B': console.log('case B'); break; c ...
  • 多個元素的過渡 點擊打開視頻講解更加詳細 我們之後討論多個組件的過渡,對於原生標簽可以使用 v-if/v-else。最常見的多標簽過渡是一個列表和描述這個列表為空消息的元素: <transition> <table v-if="items.length > 0"> <!-- ... --> </ta ...
  • process-env 在使用vue框架時,經常用到的倆種環境,一種是開發環境,一種是生產環境。 平時開發使用的是開發環境,如果發佈到線上時,需要切換為線上環境。可以通過不同配置不同的運行命令來自動切換環境。 配置環境實現原理 實現原理是採用nodeJS的頂層對象中的process.env(進程環境 ...
  • 有時候想寫一個無關框架組件,又不想用原生或者 Jquery 那套去寫,而且還要避免樣式衝突,用 Web Components 去做剛覺就挺合適的。但是現在 Web Components 使用起來還是不夠靈活,很多地方還是不太方便的,如果能和 MVVM 搭配使用就好了。早在之前 Angular 就支持 ...
  • 時隔幾個月,拖拖拉拉的終於整理好了一份使用指南。下次終於可以甩個文檔連接了🤣,再也不用一個個解釋了。 感慨 隨隨便便做的一個主題,沒想到會有人使用。🤣因為沒有文檔,時不時有人會來問怎麼使用,無奈只有一個個郵件回覆告知。體會到開源不易,維護更不易🤣(在此對曾經使用過的開源庫表示感謝)。 以前主題 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...