string转化成对象_Mobx源码阅读笔记——3. proxy 还是defineProperty,劫持对象行为的两个方案...

本文通过阅读Mobx源码,探讨了如何将字符串转化为对象并实现响应式修改。文章介绍了两种方案:1) 不使用proxy,通过defineProperty实现;2) 使用proxy直接创建响应式对象。详细分析了两者的工作原理和优缺点,特别是在对象行为劫持上的应用。
摘要由CSDN通过智能技术生成

8a8187b0b7cdabbc8849bb1d905c950e.png
上篇文章简单介绍了observable部分的架构体系,并且分析了 observableValue这个类的结构。这篇文章将会继续分析 observableObject数据类型的源码,并且顺带讨论 proxy以及 Object.defineProperty两种实现方案。

observableObject 是如何实现的?

到这里我们已经可以回答observableArray是如何实现的,通过Proxy代理Array的行为转发给ObservableArrayAdministration 实现响应式修改的逻辑。

同样我们也知道observableValue是如何实现的,一个特殊的类ObservableValue,直接使用这个类的方法甚至不需要代理。

observableObject 的实现机制比较特殊,可以说它同时实现了上述两套方案,并在创建时决定使用哪一套方案。

让我们回到第一篇文章里提到的工厂。

const observableFactories: IObservableFactories = {
    
    object<T = any>(
        props: T,
        decorators?: {
     [K in keyof T]: Function },
        options?: CreateObservableOptions
    ): T & IObservableObject {
    
        if (typeof arguments[1] === "string") incorrectlyUsedAsDecorator("object")
        const o = asCreateObservableOptions(options)
        if (o.proxy === false) {
    
            return extendObservable({}, props, decorators, o) as any
        } else {
    
            const defaultDecorator = getDefaultDecoratorFromObjectOptions(o)
            const base = extendObservable({}, undefined, undefined, o) as any
            const proxy = createDynamicObservableObject(base)
            extendObservableObjectWithProperties(proxy, props, decorators, defaultDecorator)
            return proxy
        }
    }
}

在例行公事的参数检查与options格式化之后出现了分支。通过options.proxy决定使用哪一套方案。

我们先看看proxy = false时的第一种方案

第一条路:不用proxy如何实现observableObject

这里直接返回了extendObservable的结果。extendObservable这个工具函数在mobx的文档里也有提及。

ExtendObservable 用来向已存在的目标对象添加 observable 属性。 属性映射中的所有键值对都会导致目标上的新的 observable 属性被初始化为给定值。 属性映射中的任意 getters 都会转化成计算属性。
export function extendObservable<A extends Object, B extends Object>(
    target: A,
    properties?: B,
    decorators?: {
     [K in keyof B]?: Function },
    options?: CreateObservableOptions
): A & B {
    
    //...

    const defaultDecorator = getDefaultDecoratorFromObjectOptions(options)
    initializeInstance(target) // Fixes #1740
    asObservableObject(target, options.name, defaultDecorator.enhancer) // make sure object is observable, even without initial props
    if (properties)
        extendObservableObjectWithProperties(target, properties, decorators, defaultDecorator)
    return target as any
}

首先根据options参数,选择特定的decorator 。这个过程是不是似曾相识。没错在之前的第一篇文章里我们也是通过options参数去选择特定的enhancer,这个enhancer最终作用于每一个新加入数组的item上。

实际上这里的decorator也起着类似的作用,甚至创建decorator这个过程本身也需要通过enhancer这个参数 。

export const deepDecorator = createDecoratorForEnhancer(deepEnhancer)
const shallowDecorator = createDecoratorForEnhancer(shallowEnhancer)
export const refDecorator = createDecoratorForEnhancer(referenceEnhancer)
const refStructDecorator = createDecoratorForEnhancer(refStructEnhancer)

至于decoratorenhancer是如何耦合在一起的,实际上并不只是这个函数本身看起来这么简单 。


enhancerdecorato

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值