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 ...
随机推荐
- node之body-parser的使用
bodyparser 用来解析post的请求取代了 原生的 req.on 的方式 但是只能取到ajax 和表单的数据 ,取不到上传的文件类型. let express = require('expre ...
- maven依赖包冲突解决思路
1.显示依赖关系mvn dependency:tree > tree.txt显示所有依赖关系,并输出到text.txtmvn dependency:tree -Dverbose > tre ...
- 【题解】FBI序列
题目描述 两伙外星人策划在未来的XXXX年侵略地球,侵略前自然要交换信息咯,现在,作为全球保卫队队长,你截获了外星人用来交换信息的一段仅由“F”,“B”,“I”,“O”组成的序列.为了保卫地球和平,为 ...
- 学习《Unix/Linux编程实践教程》(2):实现 more
0.目录 1.more 能做什么? 2.more 是如何实现的? 3.实现 more 3.1 more01.c 3.2 more02.c 3.3 more03.c 1.more 能做什么? more ...
- Day12-navicat for sqlite 11.1.12 patch 永久使用版
参考来源:http://www.cnblogs.com/yueyue184/p/6407963.html 深深感谢!!! 因为最近需要用这个但是网上都是注册机没有成功注册,所以就自己动手使用ollyd ...
- 算法学习——从bzoj2286开始的虚树学习生活
[原创]转载请标明原作者~ http://www.cnblogs.com/Acheing/ 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2 ...
- 谷歌AMP和百度MIP是什么鬼?
首先我们来看定义: 谷歌AMP(Accelerated Mobile Pages,加速移动页面)是Google推出的一种为静态内容构建 web 页面,提供可靠和快速的渲染,加快页面加载的时间,特别是在 ...
- linux解压
tar –xvf file.tar //解压 tar包tar -xzvf file.tar.gz //解压tar.gztar -xjvf file.tar.bz2 //解压 tar.bz2tar –x ...
- jQuery1.11源码分析(3)-----Sizzle源码中的浏览器兼容性检测和处理[原创]
上一章讲了正则表达式,这一章继续我们的前菜,浏览器兼容性处理. 先介绍一个简单的沙盒测试函数. /** * Support testing using an element * @param {Fun ...
- nginx1配置文件
1,查看日志:cat /usr/local/nginx/logs/error.log 2,编辑配置文件:vi /usr/local/nginx/conf/nginx.conf 3,内容:server ...