ES6中私有變數的實作總結(程式碼範例)
這篇文章帶給大家的內容是關於ES6中私有變數的實作總結(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
在閱讀 《ECMAScript 6 入門》的時候,零散的看到有私有變數的實現,所以在此總結一篇。
1. 約定
實作
class Example { constructor() { this._private = 'private'; } getName() { return this._private } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // private
優點
#寫法簡單
調試方便
相容性好
缺點
-
外部可以存取和修改
語言沒有配合的機制,如for in 語句會將所有屬性枚舉出來
命名衝突
2. 閉包
實作一
/** * 实现一 */ class Example { constructor() { var _private = ''; _private = 'private'; this.getName = function() {return _private} } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // undefined
優點
#無命名衝突
- ##外部無法存取和修改
- constructor 的邏輯變得複雜。建構函數應該只做物件初始化的事情,現在為了實現私有變量,必須包含部分方法的實現,程式碼組織上略不清晰。
- 方法存在於實例,而非原型上,子類別也無法使用super 呼叫
- 建構增加一點點開銷
/**
* 实现二
*/
const Example = (function() {
var _private = '';
class Example {
constructor() {
_private = 'private';
}
getName() {
return _private;
}
}
return Example;
})();
var ex = new Example();
console.log(ex.getName()); // private
console.log(ex._private); // undefined
登入後複製
優點
/** * 实现二 */ const Example = (function() { var _private = ''; class Example { constructor() { _private = 'private'; } getName() { return _private; } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex._private); // undefined
- #無命名衝突 ##外無法存取和修改
- 缺點
- 寫法有一點複雜
- 建構增加一點點開銷
- 3. Symbol
實作
const Example = (function() { var _private = Symbol('private'); class Example { constructor() { this[_private] = 'private'; } getName() { return this[_private]; } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
優點
- #無命名衝突
- 外部無法存取和修改
- 無效能損失
- #寫法稍微複雜
- 相容性也還好
- 4. WeakMap
實作
/** * 实现一 */ const _private = new WeakMap(); class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
如果這樣寫,你可能覺得封裝性不夠,你也可以這樣寫:
/** * 实现二 */ const Example = (function() { var _private = new WeakMap(); // 私有成员存储容器 class Example { constructor() { _private.set(this, 'private'); } getName() { return _private.get(this); } } return Example; })(); var ex = new Example(); console.log(ex.getName()); // private console.log(ex.name); // undefined
優點
- 無命名衝突
- ##外部無法存取和修改
- 缺點
##相容性有點問題
有一定效能代價
-
5. 最新提案
class Point { #x; #y; constructor(x, y) { this.#x = x; this.#y = y; } equals(point) { return this.#x === point.#x && this.#y === point.#y; } }
登入後複製那麼為什麼不直接使用private 欄位呢?比如說這樣:
class Foo { private value; equals(foo) { return this.value === foo.value; } }
簡單點來說,就是嫌麻煩,當然也有效能上的考量…
舉個例子,如果我們不使用#,而是使用private 關鍵字:
class Foo { private value = '1'; equals(foo) { return this.value === foo.value; } } var foo1 = new Foo(); var foo2 = new Foo(); console.log(foo1.equals(foo2));
在這裡我們新建了兩個實例,然後將foo2 作為參數傳入了foo1 的實例方法中。
那我們可以取得 foo2.value 的值嗎?如果我們直接
foo2.value肯定是取得不到值的,畢竟是私有變量,可是 equals 是 Foo 的一個類別方法,那麼可以取得的嗎?
答案是可以的。 其實這點在其他語言,比如說Java 和C 中也是一樣的,
,這是因為私有是為了實現「對外」的資訊隱藏,在類別自己內部,沒有必要禁止私有變數的訪問,你也可以理解為私有變數的限制是以類為單位,而不是以物件為單位,此外這樣做也可以為使用者帶來便利。
既然取得值是可以的,那麼列印的結果應該是 true,但是如果我們傳入的值不是 Foo 的實例,而是其他物件呢? var foo1 = new Foo();
console.log(foo1.equals({
value: 2
}));
這也意味著每次屬性存取都需要做這樣一個判斷,而引擎已經圍繞屬性存取做了高度優化,懶得改,而且還降低速度。
不過除了這個工作之外,還會有一些其他的內容需要考慮,比如說:
你必須將私有的key 編碼進每個詞法環境
for in 可以遍歷這些屬性嗎?
私有屬性和正常屬性同名的時候,誰會封鎖誰?
怎麼防止私有屬性的名稱不被偵測出來。
關於使用 # 而不使用 private 更多的討論可以參考這個 Issue。
當然這些問題都可以解決啦,就是麻煩了點。
而如果你選擇#,實作的方式將跟JavaScript 物件屬性完全沒有關係,將會使用
private slots的方式以及使用一個新的slot 尋找語法,總之就是會比private 的實作方式簡單很多。
#
以上是ES6中私有變數的實作總結(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

Django是一個由Python編寫的web應用框架,它強調快速開發和乾淨方法。儘管Django是web框架,但要回答Django是前端還是後端這個問題,需要深入理解前後端的概念。前端是指使用者直接和互動的介面,後端是指伺服器端的程序,他們透過HTTP協定進行資料的互動。在前端和後端分離的情況下,前後端程式可以獨立開發,分別實現業務邏輯和互動效果,資料的交

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

Django:前端和後端開發都能搞定的神奇框架! Django是一個高效、可擴展的網路應用程式框架。它能夠支援多種Web開發模式,包括MVC和MTV,可以輕鬆地開發出高品質的Web應用程式。 Django不僅支援後端開發,還能夠快速建構出前端的介面,透過模板語言,實現靈活的視圖展示。 Django把前端開發和後端開發融合成了一種無縫的整合,讓開發人員不必專門學習

在前端開發面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和函式庫、專案經驗、演算法和資料結構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經驗以及對行業趨勢的理解。因此,應試者應充分準備這些方面,以展現自己的能力和專業知識。
