成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Mobx 源碼初探 - observable(一)

renweihub / 1092人閱讀

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

observable 同時(shí)支持 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]);
});
本篇文章重點(diǎn)介紹 @observable 調(diào)用,其余的后續(xù)文章會(huì)繼續(xù)講解。

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

createObservable

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

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

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 的具體功能就是針對(duì)不同類(lèi)型使用不同方式的 observable。

var deepDecorator = createDecoratorForEnhancer(deepEnhancer);

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

createPropDecorator

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

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

decoratorFactory

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

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

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

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

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

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

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

initializeInstance

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

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

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

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

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

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

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

如果不存在,則給 adm 對(duì)象的 values 屬性賦值,值為 ObservableValue 的實(shí)例。

ObservableValue

ObservableValue 類(lèi)繼承 Atom 類(lèi),在實(shí)例化 ObservableValue 同時(shí),會(huì)執(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 會(huì)對(duì)原型對(duì)象進(jìn)行判斷,如果是 observable,直接返回原型對(duì)象;如果是數(shù)組,返回 observable.array 調(diào)用后結(jié)果;如果是對(duì)象,返回 observable.object 調(diào)用后結(jié)果;如果是 Map,返回 observable.map 調(diào)用后結(jié)果;如果是 Set,返回 observable.set 調(diào)用后結(jié)果;如果都不是,則直接返回傳進(jìn)來(lái)的 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 方法最后會(huì)覆蓋原型對(duì)象原有的屬性描述符,并劫持 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);
        }
    }
}

如果覺(jué)得文章不錯(cuò),對(duì)你有幫助,煩請(qǐng)點(diǎn)贊。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/106780.html

相關(guān)文章

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

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

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

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

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

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

    qieangel2013 評(píng)論0 收藏0
  • Mobx 源碼閱讀簡(jiǎn)記

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

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

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

    roundstones 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

renweihub

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<