首页 > 其他分享 >数组的劫持

数组的劫持

时间:2023-04-12 20:48:39浏览次数:45  
标签:劫持 gt 重写 inserted 数组 方法

数组的劫持

> 1. 数组劫持的思路
>
> 对于数组劫持的目标是实现数组的响应式:
>
> - 在Vue中,我们很少会使用索引进行操作数组,并且认为有七个方法能够改变数组:
>
> pushpopspliceunshiftreversesort。所以,需要对七个方法进行特殊处理,是他们能够劫持到数组的数据变化,就能够实现数组的响应式。
>
> 因此,要单独处理,在Observer初始化时会walk遍历属性实现递归;所以就需要将数组响应式的处理逻辑单独出来,重写这个七个方法:
>
> javascript > import { arrayMethods } from "./array"; > > class Observer { > constructor(value) { > if(isArray(value)){ > // 对数组类型进行单独处理:重写 7 个变异方法 > }else{ > this.walk(value); > } > } > } >
>
> 2. 数组的重写的注意
>
> 数组重写不能影响非响应式数组。
>
> 所以,对响应式数据中数组的这七个方法进行拦截:优先从链上查找到并使用重写方法啊,其他方法依然走原生逻辑。
>
> javascript > // 希望重写数组中的部分方法 > let oldArrayProto = Array.prototype; > > // newArrayProto.__proto__ = oldArrayProto > export let newArrayProto = Object.create(oldArrayProto); > > // 找到所有的变异方法 > let methods = ["push", "pop", "shift", "unshift", "reverse", "sort", "splice"]; > > methods.forEach((method) => { > // arr.push(1,2,3) > newArrayProto[method] = function (...args) { > // 重写了方法 > // push.call(arr) > const result = oldArrayProto[method].call(this, ...args); // 内部调用原来的方法,函数的劫持,切片编程 > > // 新增的数据进行劫持 > let inserted; > // 后面的 > let ob = this.__ob__; > switch (method) { > case "push": > inserted = args; > break; > case "unshift": > inserted = args; > break; > case "splice": > inserted = args.slice(2); > break; > default: > break; > } > if (inserted) { > // 对新增的内容进行观测 > ob.observeArray(inserted); > } > // 后面的 > ob.dep.notify(); > return result; > }; > }); > >
>
> - 首先,拿到数组的所有原生方法oldArrayProto,通过Object.create原型继承放到arrayMethods原型链上,相当于将原生方法向后移动了一层。
> - 当value为数组类型时,修改数组的原型链为arrayMethods;此时,原本在value.__propto__上原生方法。
> - 在arrayMrthods进行处理,在第一层对7个变异方法进行重写,利用js原型链查找机制,就实现了对原生方法的拦截。

标签:劫持,gt,重写,inserted,数组,方法
From: https://www.cnblogs.com/dgqp/p/17311149.html

相关文章

  • C# Byte数组转化String详解(c# byte转化为string)
    C#Byte数组转化String详解(c#byte转化为string)原文链接:https://www.zhiu.cn/148955.htmlC#编程过程中将Byte数组转化String是咱们常常碰到的问题,那么怎么处理C#Byte数组转化String呢?那么咱们来看看详细的涉及到的办法以及关于怎么处理C#Byte数组转化String的评论。FCL得许多......
  • JS 根据key查找对象数组中符合的一项 返回对象(递归)
    在一个复杂的数组对象数据中(嵌套多层),通过key值返回对应的对象1方法:parseJson(jsonObj,key,value){//循环所有键letarray=[]for(letvinjsonObj){letelement=jsonObj[v]//1.判断是对象或者数组if(typeof(ele......
  • c#中byte数组0x_(C#基础) byte[] 之初始化, 赋值,转换。
    c#中byte数组0x_(C#基础)byte[]之初始化,赋值,转换。原文链接:https://blog.csdn.net/weixin_39862716/article/details/111506430byte[]之初始化赋值用forloop赋值当然是最基本的方法,不过在C#里面还有其他的便捷方法。1.创建一个长度为10的byte数组,并且其中每个byte的......
  • C#中byte数组与string类型之间的转换
    C#中byte数组与string类型之间的转换原文链接:https://blog.csdn.net/weixin_44359158/article/details/116457477string类型转换为byte[]:stringstr="Test";byte[]bytTemp=System.Text.Encoding.Default.GetBytes(str);12byte[]转换为stringstringstrTemp=Sy......
  • 2023.4.12学习随笔:学贪心学到数组循环
    代码随想录(programmercarl.com)在做这个题时候发现数组循环%没看懂,就开始琢磨这一点,查了很多资料都没有讲,可能是这个知识比较基础(嘿嘿我基础太差了)慢慢来吧~ 编程的时候,很多时候都会要求一个数在某一个范围内进行反复循环,0~100循环,0~5循环等等。一般的方法是使用if语句,当判断......
  • 对象数组
    对象数组对象数组的基本介绍代码实例Person类publicclassPerson{privateStringname;privateintage;publicPerson(){}publicPerson(Stringname,intage){this.name=name;this.age=age;}publicStri......
  • 力扣 33. 搜索旋转排序数组
    整数数组nums按升序排列,数组中的值互不相同。在传递给函数之前,nums在预先未知的某个下标k(0<=k<nums.length)上进行了旋转,使数组变为[nums[k],nums[k+1],...,nums[n-1],nums[0],nums[1],...,nums[k-1]](下标从0开始计数)。例如,[0,1,2,4,5,6,7]在下标3处经......
  • C语言二维数组
    #include<stdio.h>intmain(){/**inta[3][5];通常理解a为一个三行五列的矩阵*///二维数组的遍历inta[3][5];inti,j;for(i=0;i<3;i++){for(j=0;j<5;j++){a[i][j]=i*j;}}//二......
  • LeetCode #448 找到所有数组中消失的数字
    基本思路为了满足题目要求的不使用额外的存储空间(当然返回的数组除外),并且时间复杂度控制在O(n),最多只能常数级别遍历,因此考虑将原数组视作一个"哈希表"。遍历原数组,将【1,n】上的值域映射到【0,n-】的坐标上,某个数x扫描到一次则将这个数x映射的x-1的坐标处的值加上n。......
  • C语言数组基础知识(关于索引)
    #include<stdio.h>intmain(){inti;//遍历输出分别值inta[]={1,2,3,4,5};for(i=0;i<5;i++){printf("%d\t",a[i]);//12345};printf("\n");//若给的值不够就用0补齐......