日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
如何在JavaScript對象中嵌入私有成員

最近,我開發(fā)一個(gè)項(xiàng)目 Angular Cloud Data Connector, 幫助Angular開發(fā)者使用云數(shù)據(jù),特別是 Azure移動(dòng)服務(wù), 使用WEB標(biāo)準(zhǔn),像索引數(shù)據(jù)庫(indexed DB)。我嘗試建立一種方式,使得JavaScript開發(fā)者能將私有成員嵌入到一個(gè)對象中。

創(chuàng)新互聯(lián)長期為上千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為常山企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)制作、成都做網(wǎng)站,常山網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

我解決這個(gè)問題的技術(shù)用到了我命名的閉包空間(closure space)。在這篇入門文章中,我要分享的是如何在你的項(xiàng)目中用它,及它對主流瀏覽器的性能和內(nèi)存的影響。

在深入學(xué)習(xí)前,咱們先說下,你為什么需要用到私有成員(private members), 還有一種替代方式來模擬私有成員。

如果你想點(diǎn)評本文,盡情推(twitter)我: @deltakosh。

1. 為何要用私有成員(Private Members)

當(dāng)你用JavaScript 創(chuàng)建一個(gè)對象時(shí),可以聲明值成員(value members)。 如果你打算控制對它們的讀/寫訪問操作,可以如下聲明:

 
 
  1. var entity = {};
  2. entity._property = "hello world";
  3. Object.defineProperty(entity, "property", {
  4.     get: function () { return this._property; },
  5.     set: function (value) {
  6.         this._property = value;
  7.     },
  8.     enumerable: true,
  9.     configurable: true
  10. });

這樣實(shí)現(xiàn),你能完全控制讀和寫操作。問題在于_property 成員仍然可以直接訪問和修改。

這也就是為何我們需要更加穩(wěn)定可靠的方式,聲明私有成員,它智能通過對象的方法來訪問。

#p#

2. 使用閉包空間(Closure Space)

解決方法是使用閉包空間。每當(dāng)內(nèi)部函數(shù) (inner fanction) 訪問來自外部函數(shù)作用域的變量時(shí),瀏覽器為你分配一段內(nèi)存空間。有時(shí)很取巧,不過就我們的題目來講,這算是一個(gè)***的解決方案。

我們在上個(gè)代碼版本中添加這個(gè)特性:

 
 
  1. var createProperty = function (obj, prop, currentValue) 
  2. {
  3.     Object.defineProperty(obj, prop, 
  4.     {
  5.             get: function () { return currentValue; },
  6.             set: function (value) {
  7.             currentValue = value;
  8.                     },
  9.                     enumerable: true,
  10.                     configurable: true    });
  11.                     } 
  12. var entity = {}; 
  13. var myVar = "hello world";createProperty(entity, "property", myVar);

示例中,createProperty 函數(shù)有一個(gè) currentValue 變量,存在 get 和 set 方法。此變量會(huì)保存到 get 和 set 函數(shù)的閉包空間中?,F(xiàn)在,只有這兩個(gè)函數(shù)能看到和更新 currentValue 變量! 任務(wù)完成!

唯一需要警惕 caveat,警告,注意)的是源值 (myVar) 仍可訪問。下面給出另一個(gè)更健壯的版本(保護(hù) myVar 變量):

 
 
  1. var createProperty = function (obj, prop) {
  2.     var currentValue = obj[prop];
  3.     Object.defineProperty(obj, prop, {
  4.         get: function () { return currentValue; },
  5.         set: function (value) {
  6.             currentValue = value;
  7.         },
  8.         enumerable: true,
  9.         configurable: true
  10.     });
  11. }
  12. var entity = {
  13.     property: "hello world"
  14. };
  15. createProperty(entity, "property");

采用該函數(shù), 即便源值都銷毀(destructed,注:意思是不能直接賦值)了。到此大功告成了!

#p#

3. 性能考慮Performance Considerations

現(xiàn)在咱們看看性能。

很明顯,比起一個(gè)簡單的變量,閉包空間,甚或(對象)屬性要慢的多,且更消耗資源。這就是本文更多關(guān)注普通方式和閉包空間機(jī)制差異的原因。

為證明閉包空間機(jī)制并不比標(biāo)準(zhǔn)方式更消耗資源, 我寫了下面代碼做個(gè)基準(zhǔn)測試:

 
 
  1.     
  2.     Computing...
  •     
  • 我創(chuàng)建了一百萬個(gè)對象,都有屬性成員。要完成下面三個(gè)測試:

    • 執(zhí)行 1百萬次隨機(jī)訪問屬性。

    • 執(zhí)行1百萬次隨機(jī)訪問閉包空間實(shí)現(xiàn)版本。

    • 執(zhí)行1百萬次隨機(jī)訪問常規(guī)get/set實(shí)現(xiàn)版本。

    測試結(jié)果參見下面表格和圖表:

    我們發(fā)現(xiàn),閉包空間實(shí)現(xiàn)總是快于常規(guī)實(shí)現(xiàn),根據(jù)瀏覽器的不同,還可以做進(jìn)一步的性能優(yōu)化。

    Chrome 上的性能表現(xiàn)低于預(yù)期?;蛟S存在 bug,因此,為確認(rèn)(存在 bug),我聯(lián)系了 Google 項(xiàng)目組,描述發(fā)生的癥狀。還有,如果你打算測試在 Microsoft Edge —微軟新發(fā)布的瀏覽器,在windows10 中默認(rèn)安裝—中的性能表現(xiàn),你可以點(diǎn)擊下載 。

    然而,如果仔細(xì)研究,你會(huì)發(fā)現(xiàn),使用閉包空間或?qū)傩员戎苯釉L問變量成員要10倍左右。 因此,使用要恰當(dāng)且謹(jǐn)慎。

    #p#

    4. 內(nèi)存占用(Memory Footprint)

    我們也得驗(yàn)證該技術(shù)不會(huì)消耗過多內(nèi)存。為測試內(nèi)存占用基準(zhǔn)情況,我寫了下面代碼段:

    直接屬性引用版本(Reference Code)

     
     
    1. var sampleSize = 1000000;
    2.  var entities = []; 
    3. // Creating entities
    4. for (var index = 0; index < sampleSize; index++) {
    5.     entities.push({
    6.             property: "hello world (" + index + ")"
    7. });}
    8. 常規(guī)方式版本(Regular Way,get/set)
    9. var sampleSize = 1000000;
    10. var entities = [];
    11. // Adding property and using local member to save private value
    12. for (var index = 0; index < sampleSize; index++) {
    13.     var entity = {};
    14.     entity._property = "hello world (" + index + ")";
    15.     Object.defineProperty(entity, "property", {
    16.         get: function () { return this._property; },
    17.         set: function (value) {
    18.             this._property = value;
    19.         },
    20.         enumerable: true,
    21.         configurable: true
    22.     });
    23.     entities.push(entity);
    24. }
    25. 閉包空間版本(Closure Space Version)
    26. var sampleSize = 1000000;
    27. var entities = [];
    28. var createProperty = function (obj, prop, currentValue) {
    29.     Object.defineProperty(obj, prop, {
    30.         get: function () { return currentValue; },
    31.         set: function (value) {
    32.             currentValue = value;
    33.         },
    34.         enumerable: true,
    35.         configurable: true
    36.     });
    37. }
    38. // Adding property and using closure space to save private value
    39. for (var index = 0; index < sampleSize; index++) {
    40.     var entity = {};
    41.     var currentValue = "hello world (" + index + ")";
    42.     createProperty(entity, "property", currentValue);
    43.     entities.push(entity);
    44. }

    之后,我(在三個(gè)主流瀏覽器上)運(yùn)行所有的三段代碼,啟動(dòng)(瀏覽器)內(nèi)嵌的內(nèi)存性能分析器(本示例中使用 F12 工具條):

    我計(jì)算機(jī)上運(yùn)行的結(jié)果如下圖表:

    就閉包空間和常規(guī)方式,只有 Chrome上,閉包空間(內(nèi)存占用)表現(xiàn)稍好,在 IE11 和 Firefox上占用內(nèi)存反而增多,但是瀏覽器的比較結(jié)果e—對于現(xiàn)代瀏覽器,用戶很可能不會(huì)在意這點(diǎn)差別。

    更多 JavaScript 實(shí)踐

    或許你會(huì)吃驚,微軟提供了一批有關(guān)開源 Javascript 主題的免費(fèi)學(xué)習(xí)材料, 我們正在發(fā)起一個(gè)任務(wù),關(guān)于創(chuàng)建更多 Microsoft Edge 來臨 系列。 查看我的文章:

    • 基于 HTML5 和 Babylon.JS 開發(fā) WebGL 3D 基礎(chǔ)

    • 構(gòu)建單頁面應(yīng)用,基于 ASP.NET 和 AngularJS

    • HTML 高級圖像技術(shù)

    或者我們團(tuán)隊(duì)系列:

    • HTML/JavaScript 性能優(yōu)化使用技巧 (該系列有7部分,從響應(yīng)式設(shè)計(jì)到休閑游戲的性能優(yōu)化)

    • 現(xiàn)代 Web 平臺快速起步 ( HTML, CSS, and JS基礎(chǔ))

    • 開發(fā)通用的 Windows Apps,使用 HTML 和 JavaScript 快速起步 (使用你自己的JS構(gòu)建app)

    以及一些免費(fèi)工具:Visual Studio 社區(qū),Azure 試用版和跨瀏覽器測試工具用于 Mac, Linux, 或者 Windows。

    結(jié)論(Conclusion)

    如你所見,對于創(chuàng)建真正的私有數(shù)據(jù)來講,閉包空間屬性(機(jī)制)是一個(gè)很棒的做法?;蛟S你得面對內(nèi)存消耗小幅度增加(問題),但就我的看法,這卻很合理 (這個(gè)代價(jià)可以換取相對于常規(guī)方法更高的性能增長)。

    隨帶說一句, 如果你要自己動(dòng)手試試,所以代碼可以在 here下載。 推薦一篇不錯(cuò)的文章, “how-to” on Azure Mobile Services here。


    分享名稱:如何在JavaScript對象中嵌入私有成員
    轉(zhuǎn)載源于:http://www.dlmjj.cn/article/dphijhs.html