第九章 实现isReactive和isReadonly

news2024/11/15 8:29:14

实现isReactive和isReadonly

isReactive实现

先上测试用例(其实这个测试用例也是reactive.spec.ts中追加的两个):

import { isReactive, reactive } from "../reactive"

describe('reactive',()=>{
    it('happy path',()=>{
        const original = {foo:1}
        const observed = reactive(original)
        expect(observed).not.toBe(original)
        expect(observed.foo).toBe(1)
        expect(isReactive(observed)).toBe(true)
        expect(isReactive(original)).toBe(false)
    })
})

实现:

1 reactive.ts中导出isReactive方法

2 利用isReactive传入的对象,调用对象中特定设置的一个属性__v_isReactive,如果这个对象是响应式对象,就会走get函数

3 我们可以在get函数中判断key值,如果为__v_isReactive的话,就返回他不是readonly

image.png

image.png

优化

对于这种__v_isReactive属性,我们可以使用枚举,让我们在别的地方降低书写错误

修改如下

image.png

image.png

isReadonly实现

有了isReactive的实现,那isReadonly也就水到渠成了,测试案例

image.png

实现上基本和isReactive一样

reactive.ts

image.png

image.png

最终:

reactive.ts代码

import { mutableHandlers, readonlyHandlers } from "./baseHandlers"

export const enum ReactiveFlags {
    IS_REACTIVE = "__v_isReactive",
    IS_READONLY = "__v_isReadonly"
}

export function reactive(raw){
    return createReactiveObject(raw,mutableHandlers)
}

export function readonly(raw){
    return createReactiveObject(raw,readonlyHandlers)
}

export function isReactive(value){
    return !!value[ReactiveFlags.IS_REACTIVE]
}

export function isReadonly(value){
    return !!value[ReactiveFlags.IS_READONLY]
}

function createReactiveObject(target,baseHandlers){
    return new Proxy(target,baseHandlers)
}

baseHandlers.ts

import { track, trigger } from "./effect"
import { ReactiveFlags } from "./reactive"

const get = createGetter()
const set = createSetter()
const readonlyGet = createGetter(true)

function createGetter(isReadonly = false){
    return function get(target,key){
        const res = Reflect.get(target,key)

        if(key === ReactiveFlags.IS_REACTIVE) {
            return !isReadonly
        }

        if(key === ReactiveFlags.IS_READONLY) {
            return isReadonly
        }

        if(!isReadonly) {
            track(target,key)
        }

        return res
    }
}

function createSetter() {
    return function set(target,key,value){
        const res = Reflect.set(target,key,value)

        trigger(target,key)
        return res
    }
}

export const mutableHandlers = {
    get:get,
    set:set
}

export const readonlyHandlers = {
    get:readonlyGet,
    set(target,key,value){
        console.warn(`key:${key} set 失败 因为 target 是readonly`,target)
        return true
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/382675.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

taobao.item.sku.add( 添加SKU )

¥开放平台免费API必须用户授权 新增一个sku到num_iid指定的商品中 传入的iid所对应的商品必须属于当前会话的用户 公共参数 请求地址: HTTP地址 http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 请求参数 响应参数 点击获取key和secret 请求…

第十四节 包、权限修饰符、final、常量

包 1.同一个包下的类,相互可以直接访问。 2.不同包下的类要导包后才能访问。 AIT回车键导包。 权限修饰符 什么是权限修饰符? ●权限修饰符:是用来控制一个成员能够被访问的范围。 ●可以修饰成员变量,方法,构造器,内部类&…

并发就一定快吗?答:肯定不是啊

文章目录一、多线程概念1.1 程序的并发与并行1.1.1 程序的并行1.1.2 程序的并发1.2 进程与线程1.2.1 进程1.2.2 线程1.2.3 多线程并发就一定快吗?答案直接戳这里👉:多线程并发就一定快吗? 一、多线程概念 在实际应用中&#xff…

车载测试之电子设备有哪些测试点?

现在车上大大小小的控制器大几十个,主机厂都要做哪些测试,满足哪些要求,才能使控制器达到量产要求呢? 整车开发流程 在聊测试之前,首先了解一下一款车的开发流程。在主机厂我们经常能听到“某某项目开G2阀”、“某某…

Java接口专题

基本介绍 接口给出一些没有实现的方法,封装到一起,到某个类使用时再根据具体情况把这些方法写出来。 注意:在jdk7之前,接口里所有的方法都是抽象方法。在jdk8之后接口中可以有静态方法,默认方法 interface 接口名{/…

Linux进程控制(进程终止+进程等待+进程程序替换)

文章目录:一、进程终止进程退出码常见的进程退出方法exit函数_exit函数returnexit vs _exit vs return二、进程等待进程等待的必要性进程等待的方法waitwaitpid - 从子进程获取状态信息如何获取子进程status进程的阻塞等待和非阻塞等待三、进程程序替换替换原理进程…

科技制造商必须对安全、设计选择承担更多责任

网络安全和基础设施安全局局长称当今商业网络安全的现状是"不可持续的",公司、消费者和政府必须集体转变期望,让主要软件和硬件制造商对不安全的产品负责,而不是用户。 拜登政府预计将在未来几天发布一项战略,该战略将…

burp联动xray进行被动扫描

burp联动xray进行被动扫描0、简介1、打开burp,设置转发数据包,将burp抓到的数据包,额外转发到本机的7777端口2、出现这个代表配置成功3、接着在xray里输入这串代码,让xray进行监听本机的7777端口,进行被动扫描&#xf…

操作系统笔记、面试八股(二)—— 死锁

文章目录2. 死锁2.1 死锁的必要条件2.2 死锁预防2.3 死锁避免2.3.1 银行家算法2.4 死锁检测与死锁解除2.4.1 进程-资源分配图2.4.2 死锁检测的步骤2.4.3 死锁解除方法2. 死锁 2.1 死锁的必要条件 互斥 资源必须处于非共享模式,即因此只能有一个进程访问。如果有另一…

电脑崩溃蓝屏问题如何重装系统

电脑是我们日常生活和工作中必不可少的工具,但在使用过程中,难免会遇到各种问题,例如系统崩溃、蓝屏、病毒感染等,这些问题会严重影响我们的使用体验和工作效率。而小白一键重装系统可以帮助我们快速解决这些问题,本文…

精选博客系列|加速基于同态加密的隐私保护机器学习

随着机器学习在当今的企业和软件平台中的广泛使用,跨人工智能 (AI) 平台的隐私保护技术的解决方案也显得非常重要。虽然这个想法在今天看起来很明显,但人工智能研究社区历来更专注于打破数据孤岛的界限,并将数据从一个…

在线就能用的主图设计素材,免费分享!

如何给自己的店铺商品设计专属的节日活动主图?没有节日活动的主体素材要如何设计?下面小编就分享一个在线素材设计工具,打开乔拓云,平台里面不仅有许多能使用的电商设计素材,还有许多的设计工具和模板能帮助你快速的实…

macOS 13.3 Beta 2 (22E5230e)With OpenCore 0.8.9正式版 and winPE双引导分区原版镜像

原文地址:http://www.imacosx.cn/112340.html,转载需注明出处镜像特点完全由黑果魏叔官方制作,针对各种机型进行默认配置,让黑苹果安装不再困难。系统镜像设置为双引导分区,全面去除clover引导分区(如有需要…

海外服务器:为什么越来越多的人选择跨境托管?

在数字化时代,越来越多的企业和个人需要一个高效、稳定、安全的网络服务。而以独立服务器为主的海外服务器和跨境托管服务已成为满足这种需求的重要选择。在本文中,小编将探讨海外服务器和跨境托管的优势和发展趋势。一、什么是海外服务器和跨境托管?海…

如何使用GitBleed从Git库镜像中提取数据

关于GitBleed GitBleed是一款针对Git库镜像的安全检测工具,该工具包含了多个Shell脚本,可以帮助广大研究人员下载克隆的Git库和Git库镜像,然后从中提取各种数据,并分析两者之间的不同之处。 功能介绍 工具提供的脚本能够克隆指…

Django实践-02创建应用

文章目录Django实践-02创建应用Django介绍Django项目构建Django项目安装(前一篇已经装好):创建应用1. 创建app,执行下面的命令:2. 修改视图views.py3. 修改Django项目目录下的urls.py文件4.重新运行项目5. 基于模板完成…

深度包检测(DPI)详细介绍

以前不了解这个,一个应聘职位是这个方面的,就在网上收集这个资料,了解了这个方面的资料,其实,这个核心是自然语言识别。 目录 简介背景 流量识别 常用功能具体功能 做法特征识别架构举例部署方式 串接方式并接方式存…

Mac安装Redis后的配置

Mac安装Redis后的配置找到安装目录配置文件修改启动服务做测试连接找到安装目录 1.双击(右键)访达,点击前往文件夹进行查找,如下图所示 2.然后再如下图所示中找到如下路径: usr/local/bin3.找到redis.conf即redis的…

JAVA版B2B2C商城源码多商户入驻商城

三勾商城多商户是开发友好的微信小程序商城,框架支持SAAS,支持发布 iOS Android 公众号 H5 各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)等多个平台,不可多得的二开神器, 为大中小企业提供极致的移…

hadoop的运行模式

作者简介&#xff1a;大家好我是小唐同学(๑>؂<๑&#xff09;&#xff0c;好久不见&#xff0c;为梦想而努力的小唐又回来了&#xff0c;让我们一起加油&#xff01;&#xff01;&#xff01; 个人主页&#xff1a;小唐同学(๑>؂<๑&#xff09;的博客主页 目前…