成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Mobx 源碼初探 - observable(一)

renweihub / 1046人閱讀

摘要:此時為空對象當(dāng)構(gòu)造函數(shù)原型對象上存在屬性,則執(zhí)行下面代碼。屬性名傳遞進(jìn)來的函數(shù)描述符構(gòu)造函數(shù)原型對象此時為最后通過調(diào)用函數(shù)為屬性生成描述符。初始值獲取之后,調(diào)用方法,傳入構(gòu)造函數(shù)原型對象屬性名初始值和。

observable 同時支持 decorator 方式和方法調(diào)用方式。

// 示例
@observable name = "張三";
const temp = observable.box(20);

在源碼中可以發(fā)現(xiàn) mobxobservable 上綁定了很多方法。

Object.keys(observableFactories).forEach(function(name) {
    return (observable[name] = observableFactories[name]);
});
本篇文章重點介紹 @observable 調(diào)用,其余的后續(xù)文章會繼續(xù)講解。

@observable 有一個很強大的功能,它會對于不同類型,應(yīng)用不同的轉(zhuǎn)換規(guī)則。它究竟是如何處理的?

createObservable

當(dāng)我們使用 @observable,實質(zhì)上是調(diào)用了 createObservable 的返回的 deepDecorator 函數(shù)。

createObservable 接收 3 個參數(shù) v、arg2、arg3,這三個參數(shù)分別對應(yīng)構(gòu)造函數(shù)的原型對象、屬性名、描述符。

function createObservable(v, arg2, arg3) {
    // @observable someProp;
    if (typeof arguments[1] === "string") {
        return deepDecorator.apply(null, arguments);
    }
    ...
}
createDecoratorForEnhancer

deepDecorator 函數(shù)是 createDecoratorForEnhancer 的返回值,它把 deepEnhancer 作為參數(shù)傳遞進(jìn)去。deepDecorator 的具體功能就是針對不同類型使用不同方式的 observable。

var deepDecorator = createDecoratorForEnhancer(deepEnhancer);

createDecoratorForEnhancer 函數(shù)會返回一個 res,所以說當(dāng)調(diào)用 @observable 時候就是等于執(zhí)行 res 函數(shù),傳遞進(jìn)去的 deepEnhancer 會作為 resenhancer 屬性存在。

createPropDecorator

createDecoratorForEnhancer 方法內(nèi)部會通過 createPropDecorator 函數(shù)生成 rescreatePropDecorator 函數(shù)接收 2 個參數(shù),第一個參數(shù) propertyInitiallyEnumerable 設(shè)置為 true ( 內(nèi)部寫死 ),第二個參數(shù) propertyCreator 為傳遞進(jìn)來的函數(shù)。

createPropDecorator 函數(shù)返回 decoratorFactory 函數(shù)??吹竭@里,我們先整理下,當(dāng)我們編寫 @observable,實質(zhì)上就是在調(diào)用 decoratorFactory 函數(shù)。

decoratorFactory

decoratorFactory 函數(shù)內(nèi)部定義 decorator 函數(shù),當(dāng)調(diào)用時,會先判斷當(dāng)前的調(diào)用方式,如果是 @decorator 方式調(diào)用,則直接執(zhí)行 decorator 函數(shù),否則返回 decorator 函數(shù)。

decorator 函數(shù)內(nèi)部會首先判斷構(gòu)造函數(shù)的原型對象上是否存在 __mobxDecorators 屬性,如果不存在,則定義此屬性,并通過 addHiddenProp 方法設(shè)置描述符。

function addHiddenProp(object, propName, value) {
    Object.defineProperty(object, propName, {
        enumerable: false,
        writable: true,
        configurable: true,
        value: value // 此時為空對象
    });
}

當(dāng)構(gòu)造函數(shù)原型對象上存在 __mobxDecorators 屬性,則執(zhí)行下面代碼。

target.__mobxDecorators[prop] = {
    prop: prop, // 屬性名
    propertyCreator: propertyCreator, // 傳遞進(jìn)來的函數(shù)
    descriptor: descriptor, // 描述符
    decoratorTarget: target, // 構(gòu)造函數(shù)原型對象
    decoratorArguments: decoratorArguments // 此時為 []
};
createPropertyInitializerDescriptor

最后通過調(diào)用 createPropertyInitializerDescriptor 函數(shù)為屬性生成描述符。createPropertyInitializerDescriptor 函數(shù)內(nèi)部會根據(jù)是否可枚舉進(jìn)行分類,并以屬性名作為緩存對象的 key,生成的描述符作為 value 存在。

尤其需要注意的是,描述符中有 getset 方法,這兩個方法內(nèi)部都會首先調(diào)用 initializeInstance 方法,然后才執(zhí)行對應(yīng)的數(shù)據(jù)操作。

initializeInstance

initializeInstance 方法會首先判斷原型對象是否 __mobxDidRunLazyInitializers 屬性,如果存在,則后續(xù)都不執(zhí)行。如果不存在,則會依次調(diào)用原型對象上 __mobxDecorators 屬性對應(yīng)的 propertyCreator 方法。

看到這里,可能有人就懵了,問 propertyCreator 方法哪來的?還記得我們在調(diào)用 createPropDecorator 函數(shù)傳遞進(jìn)去的第二個參數(shù)嗎?這個方法就是那來的。propertyCreator 內(nèi)部首先會判斷屬性描述符中是否存在 get,這里的屬性描述符是原有的屬性描述符,而不是封裝后的。如果存在 get 方法,則報錯,否則繼續(xù)執(zhí)行。判斷描述符是否存在,不存在則設(shè)置初始值為 undefined,存在則繼續(xù)判斷是否有 initializer 方法,如果沒有,則初始值為描述符的 value。如果有此方法,否則執(zhí)行此方法,獲取屬性初始值。

var initialValue = descriptor
    ? descriptor.initializer
        ? descriptor.initializer.call(target)
        : descriptor.value
    : undefined;
defineObservableProperty

初始值獲取之后,調(diào)用 defineObservableProperty 方法,傳入 target 構(gòu)造函數(shù)原型對象、propertyName 屬性名、initialValue 初始值和 enhancer ( deepEnhancer )。

function defineObservableProperty(target, propName, newValue, enhancer) {
    var adm = asObservableObject(target);
}
asObservableObject

asObservableObject 方法會首先判斷原型對象是否可擴展,如果不可以,則報錯。其次根據(jù)一定規(guī)則生成 name,通過調(diào)用 new ObservableObjectAdministration(target, name, defaultEnhancer) 生成 adm 對象,此對象會綁在原型對象的 $mobx 上,并返回新生成的 adm 對象。

defineObservableProperty 首先會通過調(diào)用 asObservableObject 方法獲取 adm 對象,判斷原型對象上的屬性是否可配置與可寫,如果不可以,報錯。判斷新生成的 adm 對象上是否存在 interceptors 屬性,且屬性值得長度大于 0。

如果不存在,則給 adm 對象的 values 屬性賦值,值為 ObservableValue 的實例。

ObservableValue

ObservableValue 類繼承 Atom 類,在實例化 ObservableValue 同時,會執(zhí)行 enhancer 方法,在這里即為 deepEnhancer。

var ObservableValue = (function(_super) {
    __extends(ObservableValue, _super);
    // 部分代碼
    var _this = _super.call(this, name) || this;
    _this.value = enhancer(value, undefined, name);
})(Atom);

deepEnhancer 會對原型對象進(jìn)行判斷,如果是 observable,直接返回原型對象;如果是數(shù)組,返回 observable.array 調(diào)用后結(jié)果;如果是對象,返回 observable.object 調(diào)用后結(jié)果;如果是 Map,返回 observable.map 調(diào)用后結(jié)果;如果是 Set,返回 observable.set 調(diào)用后結(jié)果;如果都不是,則直接返回傳進(jìn)來的 v。

function deepEnhancer(v, _, name) {
    if (isObservable(v)) return v;
    if (Array.isArray(v)) return observable.array(v, { name: name });
    if (isPlainObject(v)) return observable.object(v, undefined, { name: name });
    if (isES6Map(v)) return observable.map(v, { name: name });
    if (isES6Set(v)) return observable.set(v, { name: name });
    return v;
}

defineObservableProperty 方法最后會覆蓋原型對象原有的屬性描述符,并劫持 getset 操作。

Object.defineProperty(target, propName, generateComputedPropConfig(propName));

function generateComputedPropConfig(){
    // 部分
    return {
        configurable: true,
        enumerable: true,
        get: function() {
            return this.$mobx.read(this, propName);
        },
        set: function(v) {
            this.$mobx.write(this, propName, v);
        }
    }
}

如果覺得文章不錯,對你有幫助,煩請點贊。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/106780.html

相關(guān)文章

  • 【用故事解讀 MobX 源碼(五)】 Observable

    摘要:前言初衷以系列故事的方式展現(xiàn)源碼邏輯,盡可能以易懂的方式講解源碼本系列文章用故事解讀源碼一用故事解讀源碼二用故事解讀源碼三用故事解讀源碼四裝飾器和用故事解讀源碼五文章編排每篇文章分成兩大段,第一大段以簡單的偵探系列故事的形式講解所涉及人物場 ================前言=================== 初衷:以系列故事的方式展現(xiàn) MobX 源碼邏輯,盡可能以易懂的方式...

    leeon 評論0 收藏0
  • 【用故事解讀 MobX 源碼(四)】裝飾器 和 Enhancer

    摘要:所以這是一篇插隊的文章,用于去理解中的裝飾器和概念。因此,該的作用就是根據(jù)入?yún)⒎祷鼐唧w的描述符。其次局部來看,裝飾器具體應(yīng)用表達(dá)式是,其函數(shù)簽名和是一模一樣。等裝飾器語法,是和直接使用是等效等價的。 ================前言=================== 初衷:以系列故事的方式展現(xiàn) MobX 源碼邏輯,盡可能以易懂的方式講解源碼; 本系列文章: 《【用故事解...

    maybe_009 評論0 收藏0
  • 【用故事解讀 MobX源碼)】 autorun

    摘要:隨后,執(zhí)行官給出一張當(dāng)張三存款發(fā)生變化之時,此機構(gòu)的運作時序圖的確,小機構(gòu)靠人力運作,大機構(gòu)才靠制度運轉(zhuǎn)。第一條語句創(chuàng)建觀察員第一條語句張三我們調(diào)用的時候,就創(chuàng)建了對象,對象的所有屬性都將被拷貝至一個克隆對象并將克隆對象轉(zhuǎn)變成可觀察的。 ================前言=================== 初衷:網(wǎng)上已有很多關(guān)于 MobX 源碼解讀的文章,但大多閱讀成本甚高。...

    qieangel2013 評論0 收藏0
  • Mobx 源碼閱讀簡記

    摘要:源碼簡記整體會寫得比較亂,同時也比較簡單,和讀書筆記差不多,基本是邊讀邊寫。見諒主要三大部分的原子類,能夠被觀察和通知變化,繼承于。同時里面有幾個比較重要的屬性與方法。 Mobx 源碼簡記 整體會寫得比較亂,同時也比較簡單,和讀書筆記差不多,基本是邊讀邊寫。見諒~ 主要三大部分Atom、Observable、Derivation Atom Mobx的原子類,能夠被觀察和通知變化,obs...

    paulli3 評論0 收藏0
  • mobx學(xué)習(xí)總結(jié)

    摘要:原理分析的核心就是通過觀察某一個變量,當(dāng)該變量產(chǎn)生變化時,對應(yīng)的內(nèi)的回調(diào)函數(shù)就會發(fā)生變化。回調(diào)函數(shù)若依賴外部環(huán)境,則無法進(jìn)行收集很好理解,的回調(diào)函數(shù)在預(yù)執(zhí)行的時候無法到達(dá)那一行代碼,所以收集不到。 Mobx解決的問題 傳統(tǒng)React使用的數(shù)據(jù)管理庫為Redux。Redux要解決的問題是統(tǒng)一數(shù)據(jù)流,數(shù)據(jù)流完全可控并可追蹤。要實現(xiàn)該目標(biāo),便需要進(jìn)行相關(guān)的約束。Redux由此引出了dispa...

    roundstones 評論0 收藏0

發(fā)表評論

0條評論

renweihub

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<