搜尋
首頁web前端js教程JavaScript的Symbol類型、隱藏屬性及全域登錄詳解

本篇文章為大家帶來了關於javascript的相關知識,其中主要介紹了關於Symbol類型、隱藏屬性及全局註冊表的相關問題,包括了Symbol類型的描述、Symbol不會隱式轉字符串等問題,下面一起來看一下,希望對大家有幫助。

JavaScript的Symbol類型、隱藏屬性及全域登錄詳解

【相關推薦:javascript影片教學web前端

##Symbol簡介

Symbol類型是JavaScript中的一種特殊的類型,特殊在所有的Symbol類型值都互不相同。我們可以使用「Symbol」來表示唯一的值,以下是創建Symbol物件的案例:

let id = Symbol();
這樣我們就創建了一個

Symbol類型的值,並且把這個值儲存在變數id#了變數中。

Symbol類型的描述

我們在創建一個

Symbol類型變數的時候,可以在參數中傳入一些秒屬性的字串,用來描述這個變數的用途資訊。 例如:

let id1 = Symbol('狂拽酷炫吊炸天的小明的id');
let id2 = Symbol('低调奢华有内涵的婷婷的id');

Symbol類型在任何時候都是不同的,即使他們擁有相同的描述訊息,描述只是一個標籤,除此之外就沒有別的用途了,例如:

let id1 = Symbol('id');
let id2 = Symbol('id');
console.log(id1==id2);//false
這個標籤存在的意義,個人認為和

Symbol不能直觀的看到內部具體值的特性有關,通過添加一個描述信息,讓我們對變量的用途有更直觀的了解。

Symbol不會隱式轉字串

JavaScript中的大多數類型都可以直接轉換成字串型別輸出,所以我們不能直覺的看到它的值到底是什麼,例如我們可以直接用alert(123)把數字123轉換成字串彈出。 但是
Symbol類型比較特殊,它不能直接轉換,例如:

let id = Symbol();
alert(id);//报错,不能把Symbol类型转为字符串

JavaScript中的Symbol類型不能轉換成字符串是由於其內在的防治語言混亂的「語言保護」機制,因為字串和Symbol在本質上有著區別,不應該將其中一個轉換成另一個。

試想一下,如果

Symbol可以轉為字串,那麼它就變成了一個產生獨一無二字串的函數,就不再具備獨立資料類型的必要。

如果我們真的想知道

Symbol變數的值,我們可以使用.toString()方法,如下所示:

let id = Symbol('this is identification');
console.log(id.toString());//Symbol(this is identification);
或者使用

.description屬性,取得描述資訊:

let id = Symbol('加油,奥利给');
console.log(id.description);//加油,奥利给”
Symbol類似作為物件的屬性鍵

根據

JavaScript的規範,只有兩種類型的值可以作為物件的屬性鍵:

    字串
  1. Symbol
如果使用其他類型,則會隱式的轉為字串類型。物件的鍵在前面的章節有詳細的介紹,這裡不再重複。

建立Symbol鍵

Symbol作為鍵值有兩種方法: 例1:

let id = Symbol('id');
let user = {};
user[id] = 'id value';//添加Symbol键
console.log(user[id]);//id value
範例2:

let id = Symbol('id');
let user = {
	[id]:'id value',//注意这里的方括号	
};
console.log(user[id]);
以上兩個案例展示了在物件中插入

Symbol類型作為鍵的用法,需要注意的是,在存取屬性時需要使用obj[id ]而不是obj.id,因為obj.id代表的是obj['id']

如果我們使用

Symbol作為物件的鍵會有什麼效果呢?

for…in中被跳過

Symbol非常明顯的一個特徵是,如果物件中使用Symbol作為鍵,那麼使用for…in語句是存取不到Symbol類型的屬性的。

舉例:

let id = Symbol('id');
let user = {
	name : 'xiaoming',
	[id] : 'id',
};
for (let key in user) console.log(user[key]);
執行上述程式碼,得到以下結果:

> xiaoming
可以發現,

[id]物件的值沒有被列印出來,說明在物件屬性清單中,使用for … in會自動忽略Symbol類型的鍵。

同樣的,

Object.keys(user)也會忽略所有的Symbol類型的鍵。

這樣的特性能帶來非常有用的效果,例如我們可以創造出只能自己能使用的屬性。

雖然我們沒有辦法直接取得到

Symbol鍵,但Object.assign方法能夠複製所有的屬性:

let id = Symbol();
let obj = {
    [id] : '123'
}

let obj2 = Object.assign({},obj);
console.log(obj2[id]);
這並不影響

Symbol的隱藏屬性,因為複製後的物件仍然無法取得Symbol鍵。

隐藏自定义属性

由于Symbol既不能直接转为字符串,我们没有办法直观的获得它的值,又不能通过for … in获得对象的Symbol属性,也就是说,如果没有Symbol变量本身,我们就没有办法获得对象内部的对应属性。

因此,通过Symbol类型的键值,我们可以隐藏属性,这些属性只能我们自己访问,其他人都看不到我们的属性。

举个例子:

我们在开发的过程中,需要和同事“张三”合作,而这个张三创建了一个非常好用的工具ToolTool是一个对象类型,我们想白嫖张三的Tool,并在此基础上添加一些自己的属性。

我们就可以通过添加Symbol类型的键:

let tool = {//张三写好了的Tool
    usage : "Can do anything",
}

let name = Symbol("My tool obj");
tool[name] = "This is my tool";
console.log(tool[name]);

以上示例展示了如何在别人写好的对象上添加自己的属性,那么为什么要使用Symbol类型而不是常规的字符串呢?

原因如下:

  1. 对象tool是别人写好的代码,原则上我们不应该去修改别人的代码,这样会造成风险;
  2. 避免命名冲突,我们直接使用字符串很有可能会和别人原有的属性键冲突,造成严重的后果;
  3. 使用Symbol永远不会发生命名冲突,因为Symbol都是不同的;
  4. 别人无法访问Symbol类型的键,相当于不会和别人的代码冲突;

错误示范:
如果我们不使用Symbol类型,很可能出现以下情况:

let tool = {//张三写好了的Tool
    usage : "Can do anything",
}

tool.usage = "Boom Boom";
console.log(tool.usage);

以上代码由于重复使用”usage”,从而重写了原属性,会造成对象原功能异常。

Symbol全局注册表

所有的Symbol变量都是不同的,即使他们有用相同的标签(描述)。
有些时候,我们希望通过一个字符串名称(标签),访问同一个Symbol对象,例如我们在代码的不同地方访问相同的Symbol

JavaScript会维护一个全局的Symbol注册表,我们可以通过向注册表中插入Symbol对象,并为对象起一个字符串名称访问该对象。

向注册表插入或者读取Symbol对象需要使用Symbol.for(key)方法,如果注册表中有名为key的对象,就返回该对象,否则就插入新对象再返回。

举个例子:

let id1 = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let id2 = Symbol.for('id');//注册表内已有名为id的Symbol,直接返回
console.log(id1===id2);//true

我们通过Symbol.for(key)就能以全局变量的方式使用Symbol对象,并使用一个字符串标记对象的名字。

相反的,我们还可以使用Symbol.keyFor(Symbol)反向的从对象获取名称。

举个例子:

let id = Symbol.for('id');//注册表内没有名为id的Symbol,创建并返回
let name = Symbol.keyFor(id);
console.log(name);//id

Symbol.keyFor()函数只能用在全局Symbol对象上(使用Symbol.for插入的对象),如果用在非全局对象上,就会返回undefined

举个例子:

let id = Symbol('id');//局部Symbol
let name = Symbol.keyFor(id);
console.log(name);//undefined

系统Symbol

JavaScript有许多系统Symbol,例如:

  • Symbol.hasInstance
  • Symbol.iterator
  • Symbol.toPrimitive

它们各有用途,我们在后面的会逐步介绍道这些独特的变量。

总结

  1. Symbol对象的值是唯一的;
  2. Symbol可以添加一个标签,并通过标签在全局注册表中查询对象的实体;
  3. Symbol作为对象的键无法被for … in探测到;
  4. 我们可以通过Symbol到全局注册表访问全局的Symbol对象;

但是,Symbol并不是完全隐藏的,我们可以通过Object.getOwnPropertySymbols(obj)获取对象所有的Symbol,或者通过Reflect.ownKeys(obj)获取对象所有的键。

【相关推荐:javascript视频教程web前端

以上是JavaScript的Symbol類型、隱藏屬性及全域登錄詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具