arr数组怎么取值_记一次思否问答的问题思考:Vue为什么不能检测数组变动

8f1a4cee4557d81c677ae0ba87acf9f6.png

作者 | hfhan

来源 | https://segmentfault.com/a/1190000015783546

问题描述:Vue检测数据的变动是通过Object.defineProperty实现的,所以无法监听数组的添加操作是可以理解的,因为是在构造函数中就已经为所有属性做了这个检测绑定操作。

但是官方的原文:由于 JavaScript 的限制, Vue 不能检测以下变动的数组:

当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
当你修改数组的长度时,例如:vm.items.length = newLength

这句话是什么意思?我测试了下Object.defineProperty是可以通过索引属性来设置属性的访问器属性的,那为何做不了监听?

有些论坛上的人说因为数组长度是可变的,即使长度为5,但是未必有索引4,我就想问问这个答案哪里来的,修改length,新增的元素会被添加到最后,它的值为undefined,通过索引一样可以获取他们的值,怎么就叫做“未必有索引4”了呢?

既然知道数组的长度为何不能遍历所有元素并通过索引这个属性全部添加set和get不就可以同时更新视图了吗?

如果非要说的话,考虑到性能的问题,假设元素内容只有4个有意义的值,但是长度确实1000,我们不可能为1000个元素做检测操作。但是官方说的由于JS限制,我想知道这个限制是什么内容?各位大大帮我解决下这个问题,感谢万分。


面对这个问题,我想说的是,首先,长度为1000,但只有4个元素的数组并不一定会影响性能,因为js中对数据的遍历除了for循环还有forEach、map、filter、some等,除了for循环外(for,for...of),其他的遍历都是对键值的遍历,也就是除了那四个元素外的空位并不会进行遍历(执行回调),所以也就不会造成性能损耗,因为循环体中没有操作的话,所带来的性能影响可以忽略不计,下面是长度为10000,但只有两个元素的数组分别使用for及forEach遍历的结果:

var arr = [1]; arr[10000] = 1

可以看到结果非常明显,不过,如果for循环中不做操作的话两者速度差不多

其次,我要说的是,我也不知道这个限制是什么      (⇀‸↼‶)      ╮( •́ω•̀ )╭

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。数组的索引也是属性,所以我们是可以监听到数组元素的变化的

var arr = [1,2,3,4]

但是我们新增一个元素,就不会触发监听事件,因为这个新属性我们并没有监听,删除一个属性也是。

再回到题主的问题,既然数组是可以被监听的,那为什么vue不能检测vm.items[indexOfItem] = newValue导致的数组元素改变呢,哪怕这个下标所对应的元素是存在的,且被监听了的?

为了搞清楚这个问题,我用vue的源码测试了下,下面是vue对数据监测的源码:a47dff041a933a2b381fb3ef6e78f227.png

可以看到,当数据是数组时,会停止对数据属性的监测,我们修改一下源码:c85e31c7a0a8628bf6134d3413a1db98.png

使数据为数组时,依然监测其属性,然后在defineReactive函数中的get,set打印一些东西,方便我们知道调用了get以及set。这里加了个简单判断,只看数组元素的get,set879e6cb79896230d180ef5377ab4304b.png

然后写了一个简单案例,主要测试使用vm.items[indexOfItem] = newValue改变数组元素能不能被监测到,并响应式的渲染页面a4e51d2c1c54de4f673ffd9a39ed2572.png

运行页面913aa7fb2376ef2114c3265a9146b95c.png

可以看到,运行了6次get,我们数组长度为3,也就是说数组被遍历了两遍。两遍不多,页面渲染一次,可能多次触发一个数据的监听事件,哪怕这个数据只用了一次,具体的需要看尤大代码怎么写的。

就拿这个来说,当监听的数据为数组时,会运行dependArray函数(代码在上面图中get的实现里),这个函数里对数组进行了遍历取值操作,所以会多3遍get,这里主要是vue对data中arr数组的监听触发了dependArray函数。

当我们点击其中一个元素的时候,比如我点击的是3。8e11efefefe8022552a675d97e98b57e.png

可以看到会先运行一次set,然后数据更新,重新渲染页面,数组又是被遍历了两遍。

但是!!!数组确实变成响应式的了,也就是说js语法功能并不会限制数组的监测。

这里我们是用长度为3的数组测试的,当我把数组长度增加到9时。f8fc2a836cb1eb06d73f0c501ca862c6.png

可以看到,运行了18次get,数组还是被遍历了两遍,点击某个元素同理,渲染的时候也是被遍历两次。2294921e4b05cfc16fd6914f6ec783f3.png

有了上面的实验,我的结论是数组在vue中是可以实现响应式更新的,但是不明白尤大是出于什么考虑,没有加入这一功能,希望有知道的大佬们不吝赐教


2018-07-27补充

github上提问了尤大90de35abeda7f83a47802b13e0e40d08.png

dc31dabddf1198e64d72526dce597ed3.png

b7395db5660f816ebd37f209c43b86db.png

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

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

相关文章

使用 ref 对已渲染到页面的节点进行标记

一、字符串形式的 ref <input type"text" /*给标签打上标记 ipt */ ref"ipt" />拿到标记的节点&#xff0c;对其进行操作 handleClick () > {console.log(this);// 用 ref 标记了的标签&#xff0c;都会保存在 refs 里面console.log(this.refs…

JAVA之private修饰成员方法默认是final型的?

Java之private修饰成员方法默认是final型的&#xff1f; private修饰的成员方法默认是final型的&#xff1f; 用fianl声明的成员方法是最终方法&#xff0c;最终方法不能被子类覆盖&#xff08;重写&#xff09; 从表面上看这个命题是错误的&#xff0c;private访问修饰符修饰…

程序员你真的理解final关键字吗?

文章目录1、修饰类2、修饰方法3、修饰变量4、final变量修饰变量&#xff08;成员变量、局部变量&#xff09;4、1 final修饰成员变量&#xff1a;4、2 final修饰局部变量&#xff1a;5、final变量和普通变量的区别6、final与static的藕断丝连7、关于final修饰参数的争议前言 提…

axios vue 动态date_Web前端Vue系列之-Vue.js 实战

课程简介&#xff1a;课程目标&#xff1a;通过本课程的学习&#xff0c;让大家掌握Vue.js的进阶知识并在项目中应用。适用人群&#xff1a;具有一定vue开发基础的开发人员。课程概述&#xff1a;Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式Jav…

vue 组件 - 非单文件组件

一、定义组件 const school Vue.extend({name: xuexiao, // ----------------------------> 指定组件在开发者工具中显示的名字template: // ----------------------------> 模板<div>... 此处是结构</div>,data() { // ---------------------------->…

matlab安装好 启动总是闪退_在Ubuntu16.04下安装MATLAB2017b

1. 前言最近在折腾Ubuntu系统的高端机子&#xff0c;matlab这家伙的交互和可视化太方便了&#xff01;于是想在Linux下安装matlab&#xff0c;在各个版本中&#xff0c;matlab2017的性价比是非常高的&#xff0c;因此选择安装介个。阅读了很多帖子&#xff0c;综合找到几个靠谱…

vue 脚手架

一、 脚手架 初始 全局安装脚手架 npm i -g vue/cli切换到项目根目录&#xff0c;使用 vue create 项目名称 创建项目使用 npm run serve | yarn serve 启动项目 如果中途卡顿 使用 npm 淘宝镜像 npm config set registry --> https://registry.npm.taobao.orgvue 隐藏了…

这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析

前言 package com.jvm.classloader;class Father2{public static String strFather"HelloJVM_Father";static{System.out.println("Father静态代码块");} }class Son2 extends Father2{public static String strSon"HelloJVM_Son";static{Syste…

bigdecimal js 判断等于0_为啥阿里禁用BigDecimal的equals方法做等值比较

BigDecimal&#xff0c;相信对于很多人来说都不陌生&#xff0c;很多人都知道它的用法&#xff0c;这是一种java.math包中提供的一种可以用来进行精确运算的类型。很多人都知道&#xff0c;在进行金额表示、金额计算等场景&#xff0c;不能使用double、float等类型&#xff0c;…

git提交到github总是要输入密码_GitHub不为人知的秘密

本来想叫《GitHub骚操作》的&#xff0c;发现相关的文章已经有很多&#xff0c;而且和我本章要讲的内容完全不同&#xff0c;所以就换了这个也算贴切的标题。起因之前写过一篇文章《VM Manager 插件分享》&#xff0c;事后我发现有个地方不对劲&#xff01;看之前文章标题大家应…

MyBatis中大于号以及小于号的表达方式

mybatis使用的是xml格式的文件。使用>和<号的时候&#xff0c;会存在与xml的标签的规范冲突。 1.场景还原 在实际项目中&#xff0c;有很多需求需要通过设定一个具体的时间段来搜索或过滤所需的数据&#xff0c;今天笔者就mybatis中时间比较涉及到的大于&#xff0c;小于…

ug冲模标准件库_昆山兴模lt;携手gt;武汉益模,打通冲模“智能设计+精益管理”的最后一道关卡...

武汉益模科技股份有限公司是国内领先的工业互联网及智能制造的解决方案提供商&#xff0c;为模具、装备、军工、汽车、家电及等有柔性化生产需求的工厂提供专业的智能设计/信息化管理/智能加工/数字化工厂等工业软件、工业机器人自动化以及智能装备&#xff0c;拥有麦格纳、安波…

简述网络调研的作用_利用龙伯球透镜天线提升高铁4G网络覆盖

透镜天线&#xff0c;一种能够通过电磁波&#xff0c;将点源或线源的球面波或柱面波转换为平面波从而获得笔形、扇形或其他形状波束的天线。通过合适设计透镜表面形状和折射率 n&#xff0c;调节电磁波的相速以获得辐射口径上的平面波前。透镜天线吸收了许多光信息工程技术&…

SQLIntegrityConstraintViolationException: 异常解决

SQLIntegrityConstraintViolationException: Duplicate entry ‘xxx’ for key yyyzzz’异常解决 一. 异常现象 在做Java Web项目操作数据库添加数据的时候&#xff0c;突然发现曝出如下图所示异常&#xff1a; Caused by: java.sql.SQLIntegrityConstraintViolationExceptio…

一步怎么测量图片_测量不容易?15套测量仪器实操手册+自动计算表格,自学也可以...

测量不容易&#xff1f;15套测量仪器实操手册自动计算表格&#xff0c;自学也可以很多施工羡慕测量工资高&#xff0c;但是测量工资高也就意味着责任大&#xff0c;施工在休息的时候测量就下工地了&#xff0c;施工聚会的时候&#xff0c;测量在埋头苦算。如果施工想要干测量该…

Java 中判断一个字符串是否包含另外一个字符串的方法

方法一&#xff1a;indexOf(String s) 可以配合indexOf(String s)的使用&#xff0c;如果包含&#xff0c;返回的值是包含该子字符串在父类字符串中起始位置&#xff1b;如果不包含必定全部返回值为-1 public void test02() {String str1"张三";String str2"是…

速看!销冠高效给客户群发消息的秘诀

你是不是也有过这样的疑问&#xff1a;明明都是给客户群发消息&#xff0c;为什么别人的成交率那么高&#xff0c;自己却效果一般呢&#xff1f; 今天就给大家分享销冠常用的高效群发消息秘诀&#xff0c;让大家都能更好地与客户进行沟通&#xff0c;提高成交率&#xff01; …

不显示_电脑不显示桌面图标怎么办?

在现在这个社会时代中&#xff0c;人们对电脑的使用频率非常的高&#xff0c;电脑可以说已经成为了大家在生活中不可或缺的必备品。但是在使用电脑过程中的时候也都容易出现故障。那么&#xff0c;若碰上 电脑开机后只显示桌面的背景而没有任何程序和应用的情况&#xff0c;莫急…

Xshell 的基本使用

软件长这样 Xshell 链接地址 一、输入 ifconfig 查看 linux ip 地址 二、远程连接服务器 三、测试连接

Java中String类的concat方法___java的String字符串的concat()方法连接字符串和“+“连接字符串解释

Java中String类的concat方法 在了解concat&#xff08;&#xff09;之前&#xff0c;首先需要明确的是String的两点特殊性。 长度不可变值不可变 这两点从源码中对String的声明可以体现&#xff1a; private final char[] value ;其中final对应值的不可更改的特性&#xff1b…