国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

淺談JavaScript 中的延遲加載屬性模式

發(fā)布時(shí)間:2021-08-17 12:16 來(lái)源: 閱讀:0 作者:飛奔的龜龜 欄目: JavaScript 歡迎投稿:712375056

目錄

一、前言

傳統上,開(kāi)發(fā)人員在 JavaScript 類(lèi)中為實(shí)例中可能需要的任何數據創(chuàng )建屬性。對于在構造函數中隨時(shí)可用的小塊數據來(lái)說(shuō),這不是問(wèn)題。但是,如果在實(shí)例中可用之前需要計算某些數據,您可能不想預先支付該費用。例如,考慮這個(gè)類(lèi):

class MyClass {
    constructor() {
        this.data = someExpensiveComputation();
    }
}

在這里,data屬性是作為執行一些昂貴計算的結果而創(chuàng )建的。如果您不確定是否會(huì )使用該屬性,則預先執行該計算可能效率不高。幸運的是,有幾種方法可以將這些操作推遲到以后。

二、按需屬性模式

優(yōu)化執行昂貴操作的最簡(jiǎn)單方法是等到需要數據后再進(jìn)行計算。例如,您可以使用帶有 getter 的訪(fǎng)問(wèn)器屬性來(lái)按需進(jìn)行計算,如下所示:

class MyClass {
    get data() {
        return someExpensiveComputation();
    }
}

在這種情況下,直到有人第一次讀取該data屬性時(shí),您的昂貴計算才會(huì )發(fā)生,這是一種改進(jìn)。但是,每次data讀取屬性時(shí)都會(huì )執行相同的昂貴計算,這比之前的示例更糟糕,其中至少只執行了一次計算。這不是一個(gè)好的解決方案,但您可以在此基礎上創(chuàng )建一個(gè)更好的解決方案。

三、凌亂的延遲加載屬性模式

只有在訪(fǎng)問(wèn)屬性時(shí)才執行計算是一個(gè)好的開(kāi)始。您真正需要的是在該點(diǎn)之后緩存信息并僅使用緩存版本。但是您將這些信息緩存在哪里以便于訪(fǎng)問(wèn)?最簡(jiǎn)單的方法是定義一個(gè)具有相同名稱(chēng)的屬性并將其值設置為計算數據,如下所示:

class MyClass {
    get data() {
        const actualData = someExpensiveComputation();
 
        Object.defineProperty(this, "data", {
            value: actualData,
            writable: false,
            configurable: false,
            enumerable: false
        });
 
        return actualData;
    }
}

在這里,該data屬性再次定義為類(lèi)上的 getter,但這次它緩存了結果。調用Object.defineProperty()創(chuàng )建一個(gè)名為的新屬性data,該屬性具有固定值actualData,并且設置為不可寫(xiě)、可配置和不可枚舉(以匹配 getter)。之后,返回值本身。下次data訪(fǎng)問(wèn)該屬性時(shí),它將從新創(chuàng )建的屬性中讀取而不是調用 getter:

const object = new MyClass();
 
// calls the getter
const data1 = object.data;
 
// reads from the data property
const data2 = object.data;

實(shí)際上,所有計算僅在第一次data讀取屬性時(shí)完成。對該data屬性的每次后續讀取都返回緩存的版本。

這種模式的一個(gè)缺點(diǎn)是data屬性開(kāi)始是不可枚舉的原型屬性,最終是不可枚舉的自己的屬性:

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

雖然這種區別在很多情況下并不重要,但理解這種模式很重要,因為它在傳遞對象時(shí)可能會(huì )導致微妙的問(wèn)題。幸運的是,使用更新的模式很容易解決這個(gè)問(wèn)題。

四、類(lèi)的唯一自己的延遲加載屬性模式

如果您有一個(gè)用例,其中延遲加載的屬性始終存在于實(shí)例中很重要,那么您可以使用Object.defineProperty()在類(lèi)構造函數中創(chuàng )建屬性。它比前面的例子有點(diǎn)混亂,但它會(huì )確保該屬性只存在于實(shí)例上。下面是一個(gè)例子:

class MyClass {
    constructor() {

        Object.defineProperty(this, "data", {
            get() {
                const actualData = someExpensiveComputation();

                Object.defineProperty(this, "data", {
                    value: actualData,
                    writable: false,
                    configurable: false
                });

                return actualData;
            },
            configurable: true,
            enumerable: true
        });

    }
}

在這里,構造函數data使用Object.defineProperty().該屬性是在實(shí)例上創(chuàng )建的(通過(guò)使用this)并定義一個(gè) getter 并指定該屬性為可枚舉和可配置的(典型的自己的屬性)。將data屬性設置為可配置特別重要,以便您可以Object.defineProperty()再次調用它。

然后 getter 函數進(jìn)行計算并再次調用Object.defineProperty()。該data屬性現在被重新定義為具有特定值的數據屬性,并且不可寫(xiě)和不可配置以保護最終數據。然后,計算數據從 getter 返回。下次data讀取屬性時(shí),它將從存儲的值中讀取。作為獎勵,該data財產(chǎn)現在僅作為自己的財產(chǎn)存在,并且在第一次閱讀之前和之后的行為都相同:

const object = new MyClass();
console.log(object.hasOwnProperty("data"));     // true
 
const data = object.data;
console.log(object.hasOwnProperty("data"));     // true

對于類(lèi),這很可能是您要使用的模式;另一方面,對象文字可以使用更簡(jiǎn)單的方法。

五、對象字面量的延遲加載屬性模式

如果您使用對象字面量而不是類(lèi),則過(guò)程要簡(jiǎn)單得多,因為在對象字面量上定義的 getter 被定義為可枚舉的自身屬性(而不是原型屬性),就像數據屬性一樣。這意味著(zhù)您可以對類(lèi)使用凌亂的延遲加載屬性模式而對于對象來(lái)說(shuō)不會(huì )凌亂:

const object = {
    get data() {
        const actualData = someExpensiveComputation();
 
        Object.defineProperty(this, "data", {
            value: actualData,
            writable: false,
            configurable: false,
            enumerable: false
        });
 
        return actualData;
    }
};
 
console.log(object.hasOwnProperty("data"));     // true
 
const data = object.data;
console.log(object.hasOwnProperty("data"));     // true

六、結論

在 JavaScript 中重新定義對象屬性的能力提供了一個(gè)獨特的機會(huì )來(lái)緩存可能計算成本很高的信息。通過(guò)從重新定義為數據屬性的訪(fǎng)問(wèn)器屬性開(kāi)始,您可以將計算推遲到第一次讀取屬性時(shí),然后緩存結果以供以后使用。這種方法既適用于類(lèi),也適用于對象字面量,并且在對象字面量中更簡(jiǎn)單一些,因為您不必擔心您的 getter 會(huì )在原型上結束。

提高性能的最佳方法之一是避免重復執行相同的工作,因此任何時(shí)候您可以緩存結果以供以后使用,都可以加快程序的運行速度。延遲加載屬性模式等技術(shù)允許任何屬性成為緩存層以提高性能。

以上就是淺談JavaScript 中的延遲加載屬性模式的詳細內容,更多關(guān)于JS 延遲加載屬性模式的資料請關(guān)注腳本之家其它相關(guān)文章!

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

欧美又大又色又爽AAAA片| 国产在线高清理伦片A| 一个人免费观看的电影| 成人免费视频一区二区三区| 久久99久久99精品免视看| 精品国产杨幂在线观看|