日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
JavaScript中延遲加載屬性

本文轉(zhuǎn)載自微信公眾號(hào)「TianTianUp」,作者小弋 。轉(zhuǎn)載本文請(qǐng)聯(lián)系TianTianUp公眾號(hào)。

大家好,我是TianTian。

今天分享的內(nèi)容是JavaScript中延遲加載屬性模式。

改善性能的最好方法之一是避免重復(fù)兩次相同的工作。

因此,只要可以緩存結(jié)果供以后使用,就可以加快程序的速度。

諸如延遲加載屬性模式之類的技術(shù)使任何屬性都可以成為緩存層以提高性能。

這里說(shuō)到的延遲加載屬性模式就是利用的訪問(wèn)器屬性,將計(jì)算昂貴的操作推遲到需要時(shí)再使用。

場(chǎng)景

有些時(shí)候,你會(huì)在JavaScript類內(nèi)部創(chuàng)建一些屬性,它保存實(shí)例中可能需要的任何數(shù)據(jù)。

對(duì)于在構(gòu)造函數(shù)內(nèi)部隨時(shí)可用的小數(shù)據(jù)而言,這不是問(wèn)題。

但是,如果需要在實(shí)例中可用之前計(jì)算一些大數(shù)據(jù),則您可能需要執(zhí)行昂貴的計(jì)算操作。例如,考慮此類:

 
 
 
  1. class MyClass { 
  2.     constructor() { 
  3.         this.data = someExpensiveComputation(); 
  4.     } 

在這里,該data屬性是執(zhí)行一些昂貴的計(jì)算而創(chuàng)建的。

如果您不確定將使用該屬性,則提前執(zhí)行可能不太好,效率低。幸運(yùn)的是,接下來(lái)介紹幾種方法可以將這些操作推遲。

接下來(lái)主要圍繞的訪問(wèn)器屬性來(lái)展開的。

按需屬性模式

優(yōu)化執(zhí)行計(jì)算操作的最簡(jiǎn)單方法是等到需要數(shù)據(jù)后再進(jìn)行計(jì)算。

例如,您可以使用帶有g(shù)etter的data屬性來(lái)按需進(jìn)行計(jì)算,如下所示:

 
 
 
  1. class MyClass { 
  2.     get data() { 
  3.         return someExpensiveComputation(); 
  4.     } 

在這種情況下,直到有人第一次讀取該data屬性時(shí),您的昂貴的計(jì)算操作才發(fā)生,這是一種改進(jìn)。

但是,也是存在問(wèn)題的,每次data讀取屬性時(shí)都會(huì)執(zhí)行相同的昂貴計(jì)算操作,這比之前的示例(其中至少僅執(zhí)行一次計(jì)算)差。

按照我們分析的情況來(lái)看,這不是一個(gè)好的解決方案,所以可以在此基礎(chǔ)上創(chuàng)建一個(gè)更好的解決方案。

延遲加載屬性模式

只有在訪問(wèn)該屬性時(shí)才執(zhí)行計(jì)算是一個(gè)好的開始。您真正需要的是在那之后緩存信息,然后僅使用該緩存的數(shù)據(jù)結(jié)果。

但是,有個(gè)問(wèn)題需要我們考慮,您將這些信息緩存在何處以便于訪問(wèn)呢?

最簡(jiǎn)單的方法是定義一個(gè)具有相同名稱的屬性,并將其值設(shè)置為計(jì)算出的數(shù)據(jù),如下所示:

 
 
 
  1. class MyClass { 
  2.     get data() { 
  3.         const actualData = someExpensiveComputation(); 
  4.         Object.defineProperty(this, "data", { 
  5.             value: actualData, 
  6.             writable: false, 
  7.             configurable: false, 
  8.             enumerable: false 
  9.         }); 
  10.         return actualData; 
  11.     } 

在這里,該data屬性再次被定義為該類的getter,但是這一次它將緩存結(jié)果。

調(diào)用Object.defineProperty()創(chuàng)建一個(gè)名為的新屬性data,該屬性的固定值為actualData,并且被設(shè)置為不可寫,不可配置和可枚舉。

下次data訪問(wèn)該屬性時(shí),它將從新創(chuàng)建的屬性中讀取而不是調(diào)用getter:

 
 
 
  1. const object = new MyClass(); 
  2. // calls the getter 
  3. const data1 = object.data; 
  4. // reads from the data property 
  5. const data2 = object.data; 

實(shí)際上,所有計(jì)算僅在第一次讀取數(shù)據(jù)屬性時(shí)完成。數(shù)據(jù)屬性的每次后續(xù)讀取都將返回緩存的版本。這種模式的缺點(diǎn)是data屬性開始時(shí)是不可枚舉的原型屬性,最后是不可枚舉的自己的屬性:

 
 
 
  1. const object = new MyClass(); 
  2. console.log(object.hasOwnProperty("data"));     // false 
  3. const data = object.data; 
  4. console.log(object.hasOwnProperty("data"));     // true 

盡管這種區(qū)別在許多情況下并不重要,但了解這種模式很重要,因?yàn)樵趥鬟f對(duì)象時(shí),這種模式可能會(huì)引起細(xì)微的問(wèn)題。

幸運(yùn)的是,我們可以使用接下來(lái)的模式很容易解決這個(gè)問(wèn)題。

類的延遲加載屬性

如果您有一個(gè)實(shí)例,對(duì)于這個(gè)實(shí)例,延遲加載屬性存在很重要,那么您可以使用Object.defineProperty()在類構(gòu)造函數(shù)內(nèi)部創(chuàng)建該屬性。

它比前面的示例有點(diǎn)混亂,但是它將確保該屬性僅存在于實(shí)例上。這是一個(gè)例子:

 
 
 
  1. class MyClass { 
  2.     constructor() { 
  3.         Object.defineProperty(this, "data", { 
  4.             get() { 
  5.                 const actualData = someExpensiveComputation(); 
  6.                 Object.defineProperty(this, "data", { 
  7.                     value: actualData, 
  8.                     writable: false, 
  9.                     configurable: false 
  10.                 }); 
  11.                 return actualData; 
  12.             }, 
  13.             configurable: true, 
  14.             enumerable: true 
  15.         }); 
  16.     } 

我們從這個(gè)例子中可以發(fā)現(xiàn),構(gòu)造函數(shù)使用創(chuàng)建data訪問(wèn)器屬性O(shè)bject.defineProperty()。該屬性是在實(shí)例上創(chuàng)建的(使用this),定義了一個(gè)getter并指定了可枚舉和可配置的屬性。

將data屬性設(shè)置為可配置尤其重要,這樣您可以O(shè)bject.defineProperty()再次調(diào)用它。

然后,getter函數(shù)進(jìn)行計(jì)算并再次調(diào)用Object.defineProperty()。對(duì)于data來(lái)說(shuō),將該屬性重新定義為具有特定值的數(shù)據(jù)屬性,并且將其變?yōu)椴豢蓪懬也豢膳渲靡员Wo(hù)最終數(shù)據(jù)。下次data讀取該屬性時(shí),將從存儲(chǔ)的值中讀取該屬性。該data屬性現(xiàn)在僅作為自己的屬性存在,并且在第一次讀取之前和之后都具有相同的作用:

 
 
 
  1. const object = new MyClass(); 
  2. console.log(object.hasOwnProperty("data"));     // true 
  3.  
  4. const data = object.data; 
  5. console.log(object.hasOwnProperty("data"));     // true 

對(duì)于類,這很可能是您要使用的模式。另一方面,對(duì)象模式下可以使用更簡(jiǎn)單的方法。

對(duì)象的延遲加載屬性

如果使用的是對(duì)象模式而不是類,則過(guò)程要簡(jiǎn)單得多,因?yàn)樵趯?duì)象模式上定義的getter與數(shù)據(jù)屬性一樣被定義為可枚舉的自身屬性(而不是原型屬性)。這意味著您可以為類使用延遲加載屬性模式,而不會(huì)造成混亂:

 
 
 
  1. const object = { 
  2.     get data() { 
  3.         const actualData = someExpensiveComputation(); 
  4.  
  5.         Object.defineProperty(this, "data", { 
  6.             value: actualData, 
  7.             writable: false, 
  8.             configurable: false, 
  9.             enumerable: false 
  10.         }); 
  11.  
  12.         return actualData; 
  13.     } 
  14. }; 
  15. console.log(object.hasOwnProperty("data"));     // true 
  16. const data = object.data; 
  17. console.log(object.hasOwnProperty("data"));     // true 

總結(jié)

通過(guò)從重新定義為數(shù)據(jù)屬性的訪問(wèn)器屬性開始,您可以將計(jì)算推遲到第一次讀取該屬性時(shí),然后將結(jié)果緩存起來(lái)以備后用。這種方法適用于類和對(duì)象文字,并且在對(duì)象模式中更簡(jiǎn)單一些,因?yàn)槟槐負(fù)?dān)心getter最終會(huì)出現(xiàn)在原型上。


新聞標(biāo)題:JavaScript中延遲加載屬性
本文地址:http://m.5511xx.com/article/ccddpgs.html