Chuck Liu
Chuck Liu
@mygaochunming 1.这里不应该加return。不过在这段代码里加不加对结果不产生影响。不用过度解读。我是因为要证明博主的代码只需要一个小的改动即可实现继承,所以除了fix了我提到的那两个小问题,其他代码一概没动。 2.这里是因为此时a的constructor是指向Array的(这是个继承属性,继承自Array.prototype.constructor),但是a是fakeArray的实例。故把a.constructor指向真正的构造函数。
@mygaochunming @tommytroylin 我认真看了一下,确实不用在构造函数里写a.constructor = fakeArray 我当时只看了@mygaochunming 你提供的代码,没看我原来写的。就下意识的觉得这个a是用数组构造出来的,得改改constructor,没看我原来的代码 原来的代码里既然在后面写了: fakeArray.prototype.constructor = fakeArray 那肯定是不用重写a.constructor了。
@Zhangzirui ```javascript let a = [] Object.defineProperty(a, '0', {get: function(){console.log('getter'); return 1;}}) a.pop(); // 报错 ```
@Zhangzirui ```javascript let a = [{}] Object.defineProperty(a, '0', {get: function(){console.log('getter'); return 1;}}) a.pop() a.push(2) console.log(a) // 之前的getter失效 ```
@Zhangzirui 可是数组你想往里面添加任何数据的话用户肯定是arr.push(1,2,3,4)啊, 你难道想让他这样去手动添加元素? ```javascript this.$set(arr, '0', 1) this.$set(arr, '1', 2) this.$set(arr, '2', 3) this.$set(arr, '3', 4) ``` 这也就是数组使用defineProperty的问题, 你在init阶段监控一次后, 任何时刻把元素pop/splice出去了, 你的getter就失效了. 你再push的时候你就必须得让Vue手动监控一次。一旦用户又pop/splice,你又得手动监控。 同理执行 任何push\splice\pop行为 都会产生相似效果. 你就永远监控不到用户对数组的操作。
@Zhangzirui 额, 不是, 哥们是我描述的不太清楚. 这样吧, 我再解释一遍. 其实你也说了 数组本质还是个对象, pop 本质是 delete, 你 delete 了当然就监听不到了. 再次添加就需要再次 set 。 首先 Vue 是反对你用 Vue.set/delete的。 但是增删属性的需求确实是有的,并且不少,所以他俩存在的意义是保证这种需求至少可以得到满足。 **但是这种需求是低频的。而数组元素增删则是极其高频的** 你会去 set/delete data上的10个属性吗? 可能你100行代码里都没有一个this.$delete,但是对于数组而言, 你增/删10个、100个、1000个元素都是再平常不过的需求。几乎所有数组使用都伴随着高频的数组元素删除。 **同时,数组元素增删的方法是多样化的。** 举个例子,...
@lulutia 换成Array是不行的。 "因为Array构造函数执行时不会对传进去的this做任何处理。"请再理解这句话。