摘要:中有類語法,定義類變得簡單了然而,并沒有提供私有屬性。按照此思路,在中其實也很容易模擬私有成員。問題在于模擬的唯一性。在開發(fā)階段這個值仍然是不可預(yù)料的。綜上,中模擬來實現(xiàn)私有屬性的目的已經(jīng)達(dá)到了。
ES6 中有類語法,定義類變得簡單了
class Person { constructor(name) { this._name = name; } get name() { return this._name; } }
然而,并沒有提供私有屬性。比如上面的 Person 其實是希望在構(gòu)造的時候傳入 name,之后不允許修改了。不過,由于沒有私有屬性,所以難免有人會這樣干:
Person james = new Person("James"); james._name = "Tom"; // God Save Me
不過,如果想定義私有成員,也有變通的方式,比如廣為留傳的 Symbol 大法
var Person = (function() { let _name = Symbol(); class Person { constructor(name) { this[_name] = name; } get name() { return this[_name]; } } return Person; })();
其實質(zhì)在于匿名函數(shù)中的 Symbol 實例 _name 是局部變量,在外部不可訪問。而 Symbol 由于自身的唯一性特點,也沒法再造一個相同的出來,所以就模擬出來一個私有成員了。
按照此思路,在 ES5 中其實也很容易模擬私有成員。局部變量是很容易做到的,在函數(shù)范圍內(nèi) let 和 var 是一樣的效果。問題在于模擬 Symbol 的唯一性。
ES5 沒有 Sybmol,屬性名稱只可能是一個字符串,如果我們能做到這個字符串不可預(yù)料,那么就基本達(dá)到目標(biāo)。要達(dá)到不可預(yù)期,一個隨機數(shù)基本上就解決了。
var Person = (function() { var _name = "00" + Math.random(); function Person(name) { this[_name] = name; } Object.defineProperty(Person.prototype, "name", { get: function() { return this[_name]; } }); return Person; })();
如果這個程序在 Web 頁面中加載,那么每次刷新頁面 _name 的值都會不同,但并不會影響程序的邏輯,外部程序不會出現(xiàn)任何不適。
然而與 Symbol 方案相比,它的問題在于這個 _name 的值不會像 Symbol 一樣會隱藏起來,在控制臺可以用很多種辦法把它找出來——當(dāng)然在調(diào)試階段這樣做也沒什么不可以。在開發(fā)階段這個值仍然是不可預(yù)料的。
對于單個私有屬性的情況,有人會找到私有 Key 的規(guī)律,比如上面的私有 Key 就是以 "000." 開始的,遍歷對象屬性很容易找出來。在多個私有 Key 的情況下,也可以通過一些技術(shù)手段來找,比如
function getPersonNameKey() { var v = "" + Math.random(); var p = new Person(v); for (var k in p) { if (p[k] === v) { return k; } } }
但這些都是后話,做起來太費勁,一般人不會這么干。何況 Symbol 也是可以遍歷的(通過 Object.getOwnPropertySymbols()),完全可以以同樣的方法來獲取私有 Key。
綜上,ES5 中模擬 Symbol 來實現(xiàn)私有屬性的目的已經(jīng)達(dá)到了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85924.html
摘要:返回布爾值標(biāo)簽?zāi)0蹇梢跃o跟一個函數(shù)名后邊,該函數(shù)將被調(diào)用來處理這個模板字符串。其它情況下返回值為在內(nèi)部,整數(shù)和浮點數(shù)使用同樣的存儲方法,所以和被視為同一個值。 簡介 ES6目標(biāo),讓JavaScript變成一個企業(yè)級的開發(fā)語言,不僅僅限制與前端頁面的腳本語言。 標(biāo)準(zhǔn)(Standard): 用于定義與其他事物區(qū)別的一套規(guī)則 實現(xiàn)(Implementation): 某個標(biāo)準(zhǔn)的具體實施/真實實...
摘要:的類使用熟悉的關(guān)鍵字指定類繼承的函數(shù),并且可以通過方法訪問父類的構(gòu)造函數(shù)。例如繼承一個的類繼承了,術(shù)語上稱為基類,為派生類。例如注意到上例中,不僅是派生類的實例,也是派生類的實例,內(nèi)建對象繼承的實用之處是改變返回對象的類型。 和其它面向?qū)ο缶幊陶Z言一樣,ES6 正式定義了 class 類以及 extend 繼承語法糖,并且支持靜態(tài)、派生、抽象、迭代、單例等,而且根據(jù) ES6 的新特性衍...
摘要:迭代器在原有的數(shù)據(jù)結(jié)構(gòu)類型上新增了兩種類型,我們在使用的時候還可以通過自由組合的形式使用這些結(jié)構(gòu)類型達(dá)到自己想要的數(shù)據(jù)結(jié)構(gòu),這就需要一種統(tǒng)一的接口機制供我們調(diào)用處理不同的數(shù)據(jù)結(jié)構(gòu)。 引言 萬丈高樓平地起,欲練此功,必先打好基本功: ) 在了解 ES6 新增的變量類型前,我們必須先知道 JavaScript 在ES6之前,有如下六種基本數(shù)據(jù)類型:Null、Undefined、Number...
摘要:新建一個類該函數(shù)返回一個類的實例給函數(shù)傳入通過立即調(diào)用類構(gòu)造函數(shù)可以創(chuàng)建單例。派生類是指繼承自其它類的新類。在構(gòu)造函數(shù)中訪問之前要調(diào)用,負(fù)責(zé)初始化。在構(gòu)造函數(shù)中使用通常表示當(dāng)前的構(gòu)造函數(shù)名。 ES5中的近類結(jié)構(gòu) ES5以及之前的版本,沒有類的概念,但是聰明的JavaScript開發(fā)者,為了實現(xiàn)面向?qū)ο?,?chuàng)建了特殊的近類結(jié)構(gòu)。 ES5中創(chuàng)建類的方法:新建一個構(gòu)造函數(shù),定義一個方法并且賦值...
閱讀 2745·2021-09-02 15:11
閱讀 918·2019-08-26 18:18
閱讀 1874·2019-08-26 11:57
閱讀 3329·2019-08-23 16:59
閱讀 2005·2019-08-23 16:51
閱讀 2313·2019-08-23 16:11
閱讀 3132·2019-08-23 14:58
閱讀 1113·2019-08-23 11:34