通过defineProperty添加到javascript中的数组-有更好的方法吗?
目标是在2d javascript数组中创建一个动态“sum”行。以下是起点:通过defineProperty添加到javascript中的数组-有更好的方法吗?,javascript,arrays,function,Javascript,Arrays,Function,目标是在2d javascript数组中创建一个动态“sum”行。以下是起点: var m = [[1,2,3], [4,5,6]]; 因此,我们可以添加第三行: Object.defineProperty(m, 2, { get: () => m[0].map((e, i)=> e + m[1][i]) }) 所以现在我们的数组是 [[1,2,3], [4,5,6], [5,7,9]] 它起作用了!设置m[0][0]=10,我们得到 [[10,2,3], [4,5,6], [
var m = [[1,2,3], [4,5,6]];
因此,我们可以添加第三行:
Object.defineProperty(m, 2, { get: () => m[0].map((e, i)=> e + m[1][i]) })
所以现在我们的数组是
[[1,2,3], [4,5,6], [5,7,9]]
它起作用了!设置m[0][0]=10,我们得到
[[10,2,3], [4,5,6], [14,7,9]]
这正是我想要的m.length=3
如预期,因此总和行被视为数组的一部分<代码>JSON.stringify
也能按预期工作。(我有点惊讶它能起作用)
我的问题是-是否有一种方法可以生成依赖于其他部分的2d数组的部分,而不必求助于defineProperty
?这是应该避免的吗
(注意-在我最初的问题中,我已经完成了上述操作,然后将
m[2]
更改为其他内容。“属性”胜过了数组成员,这导致了一些混乱。这本身可能就是不使用上述方法的原因。抱歉。)请参见下面的结果:m[2]是一个函数。结果和你说的不一样
m=[[1,2,3],[4,5,7];
m[2]=()=>m[0]。映射((e,i)=>e+m[1][i]);
控制台日志(m);
console.log(Array.isArray(m[2]))
console.log(m[2]());
控制台日志(类型为(m[2]))代码>
它起作用了!我有点惊讶它能起作用
对。数组只是具有特殊.length
属性的对象,索引只是普通属性。这意味着如果你愿意,你可以让他们成为二传手
顺便说一句,您可以通过在getter中使用this
而不是总是引用m
来改进这一点:
var thirdRowDescriptor = {
enumerable: true,
configurable: true,
get() {
return this[0].map((x, i) => x + this[1][i]);
}
};
Object.defineProperty(m, 2, thirdRowDescriptor);
// or use the same descriptor on any other arrays
有没有更好的方法来生成依赖于其他零件的二维阵列的零件,而无需使用defineProperty
不,使用对象创建的getter。defineProperty
似乎正是您想要的。有许多其他方法可以动态地生成依赖于其他方法的数组,但没有一种方法真正使它成为外部数组的“一部分”
这是应该避免的吗
可能吧。我敢肯定它会破坏外部阵列(您添加了getter)的性能,因为引擎无法轻松优化索引访问。但是,如果这实际上只是一个两列对象,您希望向其中添加另一列,那么这应该不是问题。不要在大型阵列或动态增长/收缩的阵列上执行此操作。如果外部结构是静态的,那么使用普通对象(而不是数组)作为外部结构可能是更好的选择。一定有更多的代码没有显示出来。函数正在执行的某个地方。在执行之前,您正在调用m[2]=m[2]()
:[[1,2,3],[4,5,6],[5,7,9]。
抱歉,您是对的,我遗漏了一些内容,我将重写问题