<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        跟我學習javascript的prototype使用注意事項_javascript技巧

        來源:懂視網 責編:小采 時間:2020-11-27 21:45:36
        文檔

        跟我學習javascript的prototype使用注意事項_javascript技巧

        跟我學習javascript的prototype使用注意事項_javascript技巧:一、在prototype上保存方法 不使用prototype進行JavaScript的編碼是完全可行的,例如: function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash; this.toString = funct
        推薦度:
        導讀跟我學習javascript的prototype使用注意事項_javascript技巧:一、在prototype上保存方法 不使用prototype進行JavaScript的編碼是完全可行的,例如: function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash; this.toString = funct
        一、在prototype上保存方法

        不使用prototype進行JavaScript的編碼是完全可行的,例如:

        當創建了多個User類型的實例時,就存在問題了:不僅是name和passwordHash屬性在每個實例上都存在,toString和checkPassword方法在每個實例上都有一份拷貝。就像下圖表示的那樣:

        但是,當toString和checkPassword被定義在prototype上時,上圖就變成下面這個樣子了:

        toString和checkPassword方法現在定義在了User.prototype對象上,也就意味著這兩個方法只存在一份拷貝,并被所有的User實例共享。

        也許你會認為將方法作為拷貝放在每個實例上,會節省方法查詢的時間。(當方法定義在prototype上時,首先會在實例本身上尋找方法,如果沒有找到才會去prototype上繼續找)

        但是在現代的JavaScript執行引擎中,對方法的查詢進行了大量優化,所以這個查詢時間幾乎是不需要考慮的,那么將方法放在prototype對象上就節省了很多內存。

        二、使用閉包來保存私有數據

        JavaScript的對象系統從其語法上而言并不鼓勵使用信息隱藏(Information Hiding)。因為當使用諸如this.name,this.passwordHash的時候,這些屬性默認的訪問級別就是public的,在任何位置都能夠通過obj.name,obj.passwordHash來對這些屬性進行訪問。

        在ES5環境中,也提供了一些方法來更方便的訪問一個對象上所有的屬性,比如Object.keys(),Object.getOwnPropertyNames()。所以,一些開發人員使用一些規約來定義JavaScript對象的私有屬性,比如最典型的是使用下劃線作為屬性的前綴來告訴其他開發人員和用戶這個屬性是不應該被直接訪問的。

        但是這樣做,并不能從根本上解決問題。其他開發人員和用戶還是能夠對帶有下劃線的屬性進行直接訪問。對于確實需要私有屬性的場合,可以使用閉包進行實現。

        從某種意義而言,在JavaScript中,閉包對于變量的訪問策略和對象的訪問策略是兩個極端。閉包中的任何變量默認都是私有的,只有在函數內部才能訪問這些變量。比如,可以將User類型實現如下:

        此時,name和passwordHash都沒有被保存為實例的屬性,而是通過局部變量進行保存。然后根據閉包的訪問規則,實例上的方法可以對它們進行訪問,而在其它地方則不能。

        使用這種模式的一個缺點是,利用了局部變量的方法都需要被定義在實例本身上,不能講這些方法定義在prototype對象上。正如在Item34中討論的那樣,這樣做的問題是會增加內存的消耗。但是在某些特別的場合下,即使將方法定義在實例上也是可行的。

        三、實例狀態只保存在實例對象上

        一個類型的prototype和該類型的實例之間是”一對多“的關系。那么,需要確保實例相關的數據不會被錯誤地保存在prototype之上。比如,對于一個實現了樹結構的類型而言,將它的子節點保存在該類型的prototype上就是不正確的:

        當狀態被保存到了prototype上時,所有實例的狀態都會被集中地保存,在上面這種場景中顯然是不正確的:本來屬于每個實例的狀態被錯誤地共享了。如下圖所示:

        正確的實現應該是這樣的:

        此時,實例狀態的存儲如下所示:

        可見,當本屬于實例的狀態被共享到prototype上時,也許會產生問題。在需要在prototype上保存狀態屬性前,一定要確保該屬性是能夠被共享的。

        總體而言,當一個屬性是不可變(無狀態)的屬性時,就能將它保存在prototype對象上(比如方法能夠被保存在prototype對象上就是因為這一點)。當然,有狀態的屬性也能夠被放在prototype對象上,這要取決于具體的應用場景,典型的比如用來記錄一個類型實例數量的變量。使用Java語言作為類比的話,這類能夠存儲在prototype對象上的變量就是Java中的類變量(使用static關鍵字修飾)。

        四、避免繼承標準類型

        ECMAScript標準庫不大,但是提供了一些重要的類型如Array,Function和Date。在一些場合下,你也許會考慮繼承其中的某個類型來實現特定的功能,但是這種做法并不被鼓勵。

        比如為了操作一個目錄,可以讓目錄類型繼承Array類型如下:

        但是可以發現,dir.length的值是0,而不是期待中的3。

        發生這種現象的原因在于:只有當對象是真正的Array類型時,length屬性才會起作用。

        在ECMAScript標準中,定義了一個不可見的內部屬性被稱為 [[class]]。該屬性的值只是一個字符串,所以不要被誤導認為JavaScript也實現了自己的類型系統。所以,對于Array類型,這個屬性的值就是“Array”;對于Function類型,這個屬性的值就是“Function”。下表是ECMAScript定義的所有[[class]] 值:

        那么當對象的類型確實是Array時,length屬性的特別之處就在于:length的值會和該對象中被索引的屬性個數保持一致。比如對于一個數組對象arr,arr[0]和arr[1]就表示該對象有兩個被索引的屬性,那么length的值就是2。當添加了arr[2]的時候,length的值會被自動同步成3。同樣地,當設置length值為2時,arr[2]會被自動設置成undefined。

        但是當繼承Array類型并創建實例時,該實例的 [[class]] 屬性并不是Array,而是Object。因此length屬性不能正確的工作。

        在JavaScript中,也提供了用于查詢 [[class]] 屬性的方法,即使用Object.prototype.toString方法:

        因此,更好的實現方法是使用組合而不是繼承:

        以上代碼將不再使用繼承,而是將一部分功能代理給內部的entries屬性來實現,該屬性的值是一個Array類型對象。

        ECMAScript標準庫中,大部分的構造函數都會依賴內部屬性值如 [[class]] 來實現正確的行為。對于繼承這些標準類型的子類型,無法保證它們的行為是正確的。因此,不要繼承ECMAScript標準庫中的類型如:
        Array, Boolean, Date, Function, Number,RegExp,String

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        跟我學習javascript的prototype使用注意事項_javascript技巧

        跟我學習javascript的prototype使用注意事項_javascript技巧:一、在prototype上保存方法 不使用prototype進行JavaScript的編碼是完全可行的,例如: function User(name, passwordHash) { this.name = name; this.passwordHash = passwordHash; this.toString = funct
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲另类小说图片| 亚洲AV成人片色在线观看| 亚洲乱码在线播放| 久久久久久毛片免费播放| 亚洲Av无码精品色午夜| 国产午夜精品久久久久免费视| 久久亚洲2019中文字幕| 青青久久精品国产免费看| 亚洲性久久久影院| 一级做a爰性色毛片免费| 国产综合精品久久亚洲| 久久一区二区免费播放| 亚洲成A∨人片在线观看不卡| a级毛片毛片免费观看永久| 久久青草亚洲AV无码麻豆| 日韩插啊免费视频在线观看 | 18禁无遮挡无码国产免费网站 | 亚洲国产美女精品久久久久| 182tv免费视视频线路一二三| 亚洲国产精品免费在线观看| 最新欧洲大片免费在线| 日韩欧美亚洲国产精品字幕久久久| 国产成人3p视频免费观看| 一进一出60分钟免费视频| 亚洲国产AV无码专区亚洲AV| 999国内精品永久免费观看| 亚洲熟妇AV一区二区三区宅男| 国产99视频精品免费视频7| 一级成人生活片免费看| 亚洲av不卡一区二区三区| 91视频国产免费| 免费国产va在线观看| 亚洲av之男人的天堂网站| 在线看片韩国免费人成视频| 亚洲精品乱码久久久久久V| 狠狠亚洲狠狠欧洲2019| 台湾一级毛片永久免费| 无码精品人妻一区二区三区免费 | 伊人久久大香线蕉亚洲| 无码人妻精品中文字幕免费| 亚洲jjzzjjzz在线播放|