Mobxソースの初心者-observable(一)
6889 ワード
observable
は、decorator
方式と方法呼び出し方式とを同時にサポートする.//
@observable name = ' ';
const temp = observable.box(20);
ソースコードの中でmobx
がobservable
にバインドされていることが分かります.Object.keys(observableFactories).forEach(function(name) {
return (observable[name] = observableFactories[name]);
});
この文章のポイントを紹介します.@observable
呼び出し、残りの後の文章は引き続き説明します.@observable
は、異なるタイプに対して異なる変換ルールを適用する強力な機能を有する.一体どうやって処理しますか?createObservable
@observable
を使用すると、実質的にはcreateObservable
のリターンを呼び出すdeepDecorator
関数である.createObservable
は、3つのパラメータv
、arg2
、arg3
を受信し、これらの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
の関数を実行することに等しく、渡されたdeepEnhancer
はres
のenhancer
の属性として存在する.createPropDecorator
createDecoratorForEnhancer
方法の内部はcreatePropDecorator
関数によってres
を生成する.createPropDecorator
関数は2つのパラメータを受信し、第1のパラメータpropertyInitiallyEnumerable
はtrue
(内部書込み死)に設定され、第2のパラメータpropertyCreator
は伝達された関数である.createPropDecorator
関数はdecoratorFactory
関数を返します.ここを見て、私達は先に整理して、@observable
を編纂する時、実質的にdecoratorFactory
関数を呼び出しています.decorator Factory
decoratorFactory
関数の内部定義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 Instance
initializeInstance
方法は、まず、プロトタイプオブジェクト__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 Value
ObservableValue
クラスは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);
}
}
}
文章がいいと思いますが、あなたに助けがあります.いいですね.