vue 数组
今天项目中发现的一个问题:
在vue项目中输出一个数组,明明有俩个值:0,6,但是length为1
正常的是这样的
结果研究发现,是vue源码的问题,具体内容如下:
转载自:http://www.cnblogs.com/Darlietoothpaste/p/6682407.html
Vue的数组操作的实现代码大致如下:
- const aryMethods = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'];
- const arrayAugmentations = [];
- aryMethods.forEach((method)=> {
- // 这里是原生Array的原型方法
- let original = Array.prototype[method];
- // 将push, pop等封装好的方法定义在对象arrayAugmentations的属性上
- // 注意:是属性而非原型属性
- arrayAugmentations[method] = function () {
- console.log('我被改变啦!');
- // 调用对应的原生方法并返回结果
- return original.apply(this, arguments);
- };
- });
- let list = ['a', 'b', 'c'];
- // 将我们要监听的数组的原型指针指向上面定义的空数组对象
- // 别忘了这个空数组的属性上定义了我们封装好的push等方法
- list.__proto__ = arrayAugmentations;
- list.push('d'); // 我被改变啦! 4
- // 这里的list2没有被重新定义原型指针,所以就正常输出
- let list2 = ['a', 'b', 'c'];
- list2.push('d'); //
在Vue的官方文档中,有着如下的提示:
- 当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
vm.items.length = newLength
这个是Js语法的限制,什么限制呢?
先来看一下,在这篇文章中写到,为什么不利用如下的代码来实现:
- function FakeArray() {
- return Array.call(this,arguments);
- }
- FakeArray.prototype = [];
- FakeArray.prototype.constructor = FakeArray;
- FakeArray.prototype.push = function () {
- console.log('我被改变啦');
- return Array.prototype.push.call(this,arguments);
- };
- let list = ['a','b','c'];
- let fakeList = new FakeArray(list);
然而,作者在测试代码的时候,发现fakeList实际上是一个数组,而且它的push是内置的push方法,并不是继承FakeArray的方法。
在作者文章的评论中,有个网友评论说,这是因为Array.call并不会引用this,不止Array,String,Number,Regexp,Object等等JS的内置类都不行。
所以实际上代码是这样的:
- function FakeArray() {
- return Array(arguments);
- }
这也就是ES5以下无法完美继承数组的问题,回过头看一下Vue中的实现,Vue的作者用的是__proto__属性,该属性指向构造对象的原型。
也就是说,上面的例子我们可以这样改写:
- function FakeArray() {
- var x = Array.call(null,arguments);
- x.__proto__ = FakeArray.prototype
- return x;
- }
- FakeArray.prototype = [];
- FakeArray.prototype.constructor = FakeArray;
- FakeArray.prototype.push = function () {
- console.log('我被改变啦');
- return Array.prototype.push.call(this,arguments);
- };
- let list = ['a','b','c'];
- let fakeList = new FakeArray(list);
但是呢,这样写,也就意味着我们不能检测到length,和fakeList[x] = 1;这样的操作,也就有了Vue文档中的提示了。
本文参考自https://github.com/youngwind/blog/issues/85及其评论。
vue 数组的更多相关文章
- [one day one question] Vue数组变更不能触发刷新
问题描述:Vue数组变更不能触发刷新,特别是数组的每个元素都是对象的时候,对象中某个属性的值发生变化,根本无法触发Vue的dom刷新,这怎么破? 解决方案:this.$set(array, index ...
- vue 数组渲染问题
vue 数组渲染问题 问题一: 用v-for循环渲染数组数据时,数据更新了,视图却没有更新 由于 JavaScript 的限制, Vue 不能检测以下变动的数组: 1. 当你利用索引直接设置一个项时, ...
- vue数组变异方法
Vue数组变异方法,会改变被这些方法调用的原始数组,将会触发视图更新 push() 接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度 pop() 从数组末尾移除最后一项,减少数组的 ...
- Vue数组更新及过滤排序
前面的话 Vue为了增加列表渲染的功能,增加了一组观察数组的方法,而且可以显示一个数组的过滤或排序的副本.本文将详细介绍Vue数组更新及过滤排序 变异方法 Vue 包含一组观察数组的变异方法,它们将会 ...
- vue 数组 新增元素 响应式原理 7种方法
1.问题 思考一个问题,以下代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...
- vue 数组更新 this.$set(this.dataList, data.index, data.data)
vue 数组更新 this.$set(this.dataList, data.index, data.data) https://www.cnblogs.com/huangenai/p/9836811 ...
- vue 数组和对象渲染问题
vue 数组和对象渲染问题 最近项目有点忙碌,遇到好多问题都没有总结(╥﹏╥),在开发过程中,取vuex中的数组渲染完成之后,再次修改数组的值,数据更新了,但是视图并没有更新.以为是数组更新的问题,后 ...
- vue 数组对接字符串 传值时候,join(',') 一下 watch
vue 数组对接字符串 传值时候,join(',') 一下 watch watch: { 'tFill.otherDescArr': function (newVal, oldVal) { this. ...
- vue数组更新界面无变化
1. vue数组更新界面无变化 1.1. 说明 对数组进行更新或者添加,一定要注意方式,我的情况是数组套数组,双重循环,在造数据的时候,不断从尾部添加数据,所以写成了如下形式,每次下拉都会去加载一批相 ...
- WTF!! Vue数组splice方法无法正常工作
当函数执行到this.agents.splice()时,我设置了断点.发现传参index是0,但是页面上的列表项对应的第一行数据没有被删除, WTF!!! 这是什么鬼!然后我打开Vue Devtool ...
随机推荐
- Oracle DROPtable以及Truncate table 的简单测试
1. 一个用户库 有一个业务表比较大 大小是 49g 表的行数为:121546147 一亿两千万行 制作一个虚拟机的快照测试一下 drop table 和 truncate table的性能差距 2. ...
- Java线程池停止空闲线程是否有规则呢?
Java线程池中线程的数量超过核心线程的数量,且所有线程空闲,空闲时间超过keepAliveTime,会停止超过核心线程数量的线程,那么会保留哪些线程呢?是不是有规则呢? 测试代码: ThreadPo ...
- Tether USDT 节点钱包的安装与使用-omni layer
1 什么是Omni Layer Omni Layer是一种通信协议,它使用比特币区块链实现智能合约,用户货币和分散式点对点交换等功能. Omni Core是基于比特币核心代码库的快速,便携式Omni层 ...
- P3254 圆桌问题
题目链接 非常简单的一道网络流题 我们发现每个单位的人要坐到不同餐桌上,那也就是说每张餐桌上不能有同一单位的人.这样的话,我们对于每个单位向每张餐桌连一条边权为1的边,表示同一餐桌不得有相同单位的人. ...
- SQL问题(面试题)
面试完后在本地mysql数据库中重现了该问题 数据表stuscore信息如下: 1.计算每个人的总成绩,并且排名(要求显示字段 学号 姓名 总成绩)SELECT stuid AS 学号,NAME AS ...
- MT【77】函数的定义理解
答案:D.比如C 中令$x^2+1=2,x=-1,1,$ 得$f(2)=0,2$与定义矛盾,A,B同理排除. D中注意到$x^2-2x$与$|x-1|$对称轴都是$x=1$. 评:函数的定义,首先是两 ...
- BZOJ 4540 [Hnoi2016]序列 | 莫队 详细题解
传送门 BZOJ 4540 题解 --怎么说呢--本来想写线段树+矩阵乘法的-- --但是嘛--yali的机房太热了--困--写不出来-- 于是弃疗,写起了莫队.(但是我连莫队都想不出来!) 首先用单 ...
- raft 论文
raft 论文,摘自 http://www.infoq.com/cn/articles/raft-paper raft动画:https://raft.github.io/ raft说明动画:
- IOI2018题解
只有部分题解 练习赛 T2 自然还是要简单考虑了 0~n-1的排列,考虑相对的大小 我们先考虑对于前三个:a,b,c 询问a,b,询问b,c,再询问a,b,c 发现,如果三个知道两个,那么第三个可以唯 ...
- python之旅:网络编程
一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务端为你提供视频 ...