Mobxソースの初心者-observable(一)


observableは、decorator方式と方法呼び出し方式とを同時にサポートする.
//   
@observable name = '  ';
const temp = observable.box(20);
ソースコードの中でmobxobservableにバインドされていることが分かります.
Object.keys(observableFactories).forEach(function(name) {
    return (observable[name] = observableFactories[name]);
});
この文章のポイントを紹介します.@observable呼び出し、残りの後の文章は引き続き説明します.@observableは、異なるタイプに対して異なる変換ルールを適用する強力な機能を有する.一体どうやって処理しますか?
createObservable@observableを使用すると、実質的にはcreateObservableのリターンを呼び出すdeepDecorator関数である.createObservableは、3つのパラメータvarg2arg3を受信し、これらの3つのパラメータは、それぞれ、構造関数のプロトタイプオブジェクト、属性名、ディスクリプタに対応する.
function createObservable(v, arg2, arg3) {
    // @observable someProp;
    if (typeof arguments[1] === 'string') {
        return deepDecorator.apply(null, arguments);
    }
    ...
}
createDecorFor EnhancerdeepDecorator関数は、createDecoratorForEnhancerの戻り値であり、deepEnhancerをパラメータとして伝達する.deepDecoratorの具体的な機能は、異なるタイプのために異なる方法を使用するobservableである.
var deepDecorator = createDecoratorForEnhancer(deepEnhancer);
createDecoratorForEnhancerの関数はresに戻るので、@observableを呼び出したときはresの関数を実行することに等しく、渡されたdeepEnhancerresenhancerの属性として存在する.
createPropDecoratorcreateDecoratorForEnhancer方法の内部はcreatePropDecorator関数によってresを生成する.createPropDecorator関数は2つのパラメータを受信し、第1のパラメータpropertyInitiallyEnumerabletrue(内部書込み死)に設定され、第2のパラメータpropertyCreatorは伝達された関数である.createPropDecorator関数はdecoratorFactory関数を返します.ここを見て、私達は先に整理して、@observableを編纂する時、実質的にdecoratorFactory関数を呼び出しています.
decorator FactorydecoratorFactory関数の内部定義decorator関数は、呼び出し時に、まず現在の呼び出し方式を判断し、@decorator方式で呼び出した場合には、decorator関数を直接実行し、そうでなければdecorator関数に戻る.decorator関数の内部では、まず、構造関数のプロトタイプオブジェクトに__mobxDecorators属性があるかどうかを判断し、存在しない場合は、この属性を定義し、addHiddenProp法によりディスクリプタを設定します.
function addHiddenProp(object, propName, value) {
    Object.defineProperty(object, propName, {
        enumerable: false,
        writable: true,
        configurable: true,
        value: value //       
    });
}
構造関数プロトタイプオブジェクトに__mobxDecorators属性がある場合、以下のコードが実行されます.
target.__mobxDecorators[prop] = {
    prop: prop, //    
    propertyCreator: propertyCreator, //        
    descriptor: descriptor, //    
    decoratorTarget: target, //         
    decoratorArguments: decoratorArguments //     []
};
createPropertyInitializer Descriptor
最後に、createPropertyInitializerDescriptor関数を呼び出して属性の記述子を生成する.createPropertyInitializerDescriptor関数内部には、エニュメレート・オブザーバーkeyとして、作成された記述子がvalueとして存在する.
特に、説明器にはgetおよびsetの方法があり、これらの2つの方法の内部は、まずinitializeInstanceの方法を呼び出してから対応するデータ動作を実行する.
initialize InstanceinitializeInstance方法は、まず、プロトタイプオブジェクト__mobxDidRunLazyInitializersの属性があるかどうかを判断し、ある場合は、その後は実行しない.存在しない場合は、プロトタイプオブジェクト__mobxDecoratorsの属性に対応するpropertyCreator方法を順次呼び出します.
ここを見たら、誰かがぼんやりしているかもしれません.propertyCreator方法はどこから来たのですか?createPropDecorator関数を呼び出して渡された第二のパラメータを覚えていますか?この方法はあそこから来たのです.propertyCreator内部では、まず、属性記述子にgetが存在するかどうかを判断し、ここでの属性記述子はパッケージ後のものではなく、既存の属性記述子である.getの方法がある場合、エラーが発生します.そうでなければ、続行します.ディスクリプタが存在するかどうかを判断し、存在しない場合は初期値をundefinedに設定し、存在する場合はinitializerの方法があるかどうかを判断し続ける.ない場合は初期値はディスクリプタのvalueである.この方法がある場合は、属性の初期値を取得します.
var initialValue = descriptor
    ? descriptor.initializer
        ? descriptor.initializer.call(target)
        : descriptor.value
    : undefined;
defineObservable Property
初期値取得後、defineObservablePropertyメソッドを呼び出し、targetプロトタイプオブジェクト、propertyName属性名、initialValue初期値、enhancerに入る(deepEnhancer).
function defineObservableProperty(target, propName, newValue, enhancer) {
    var adm = asObservableObject(target);
}
asObservable ObjectasObservableObject方法は、まず原型オブジェクトが拡張可能かどうかを判断し、できなければエラーとします.次に、一定の規則に基づいてnameを生成し、new ObservableObjectAdministration(target, name, defaultEnhancer)を呼び出してadmオブジェクトを生成する.このオブジェクトは、プロトタイプの$mobxに縛られ、新たに生成されたadmオブジェクトに戻る.defineObservablePropertyは、まずasObservableObjectを呼び出してadmオブジェクトを取得し、原型オブジェクト上の属性が書き込み可能であるかどうかを判断する.新たに生成されたadmオブジェクトにinterceptors属性があるかどうかを判断し、属性値は0よりも長い.
存在しない場合は、admオブジェクトにvalues属性の値を割り当て、ObservableValueの例を示す.
Observable ValueObservableValueクラスはAtomクラスを継承し、実装ObservableValueと同時にenhancer方法を実行し、ここでdeepEnhancerとなる.
var ObservableValue = (function(_super) {
    __extends(ObservableValue, _super);
    //     
    var _this = _super.call(this, name) || this;
    _this.value = enhancer(value, undefined, name);
})(Atom);
deepEnhancerは、原型オブジェクトを判断し、observableであれば、直接原型オブジェクトに戻る.配列であれば、observable.arrayを呼び出した後の結果を返します.オブジェクトであれば、observable.objectに呼び出された結果を返します.Mapであれば、observable.mapを呼び出した後の結果を返します.Setであれば、observable.setを呼び出した後の結果を返します.全部でないなら、直接に伝わった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方法は、最終的には、プロトタイプオブジェクトの固有の属性記述子をカバーし、getおよびsetをハイジャックして動作する.
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);
        }
    }
}
文章がいいと思いますが、あなたに助けがあります.いいですね.