【问题标题】:Adding to an array in javascript via defineProperty - is there a better way?通过defineProperty添加到javascript中的数组 - 有没有更好的方法?
【发布时间】:2016-09-17 09:43:35
【问题描述】:

目标是在 2d javascript 数组中创建动态“求和”行。这是起点:

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 也按预期工作。 (我有点惊讶它起作用了)。

我的问题是 - 有没有一种方法可以生成依赖于其他部分的二维数组的部分而不诉诸 defineProperty?这是要避免的吗?

(注意 - 在我最初的问题中,我已经完成了上述操作,然后将 m[2] 更改为其他内容。“属性”赢得了数组成员,这导致了一些混乱。这本身可能是不这样做的原因使用上述方法。道歉。)

【问题讨论】:

  • 必须有更多您没有显示的代码。某处函数正在执行。
  • 你在某处打电话给m[2]=m[2]() 之前有:[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 5, 7, 9 ] ]

标签: javascript arrays function


【解决方案1】:

有效!我有点惊讶它的效果。

是的。数组只是具有特殊.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

有没有更好的方法来生成依赖于其他部分的 2d 数组的部分而不使用 defineProperty?

不,使用Object.defineProperty 创建的吸气剂似乎正是您想要的。还有许多其他方法可以动态生成依赖于其他数组的数组,但没有一种方法真正使它成为外部数组的“一部分”。

这是要避免的吗?

可能。我很确定它会破坏外部数组(您向其中添加了 getter)的性能,因为引擎无法轻松优化索引访问。但是,如果这真的只是一个两列对象,您想向其中添加另一列,那么这应该不是问题。只是不要在大型​​数组或动态增长/缩小的数组上执行此操作。也许使用普通对象(不是数组)作为外部结构会是更好的选择,如果它的结构无论如何都是静态的。

【讨论】:

    【解决方案2】:

    见下面的结果:m[2] 是一个函数。结果和你说的不一样。

    m = [[1, 2, 3], [4, 5, 7]];
    m[2] = () => m[0].map((e, i) => e + m[1][i]);
    
    console.log(m);
    console.log(Array.isArray(m[2]))
    console.log(m[2]());
    console.log(typeof(m[2]));

    【讨论】:

    • 道歉,你是对的,我错过了一些东西,我会重写问题
    猜你喜欢
    • 1970-01-01
    • 2016-08-19
    • 2021-07-12
    • 2023-02-05
    • 2019-04-15
    • 1970-01-01
    • 2022-07-12
    • 2015-02-17
    • 2013-03-05
    相关资源
    最近更新 更多