【问题标题】:JavaScript: Property descriptors are ignored when passed to a functionJavaScript:传递给函数时忽略属性描述符
【发布时间】:2019-07-23 21:28:02
【问题描述】:

我想将 getter/setter 传递给函数,但不能。甚至可以在 JS 中做(或模仿)这样的事情吗?

我尝试使用 getter/setter 调用一个函数,但它(很明显)不起作用,我尝试了“应用”和“调用”,但它仍然(不知何故)不起作用。

function foo(x, y) {
  var i;

  for (i = 0; i < 5; ++i)
    console.log(x, y);
}

var args = [];

Object.defineProperties(args, {
  "0": {
    "set": function() { },
    "get": Math.random
  },

  "1": {
    "set": function() { },
    "get": function() { return new Date().getMilliseconds(); }
  }
});

foo.apply(this, args);

预期 5 个不同的结果,却得到 5 个相同的结果。

【问题讨论】:

  • 我可能会产生误解,但在我看来,当您通过 apply 方法将 args 传递给 foo 时,该程序将生成 xy 的随机值- 但是一旦进入foo,这些参数是固定的,foo 只是打印出这些固定值 5 次。连续多次执行foo.apply(null, args) 会更有趣(这里foo 内部的循环无关紧要),然后我猜你每次都会得到不同的结果。
  • 顺便说一句,在 ES6 中调用foo(...args) 比使用apply 更惯用

标签: javascript arguments descriptor function-call propertydescriptor


【解决方案1】:

问题在于.apply 将您的“数组”转换为arguments 对象,因此您的访问器只会被评估一次。

您可以通过将数组直接传递给函数来使您的示例正常工作:

function foo(arr) {
  for (var i = 0; i < 5; ++i)
    console.log(arr[0], arr[1]);
}

var args = [];
Object.defineProperties(args, {
  "0": {
    "set": function() { },
    "get": Math.random
  },

  "1": {
    "set": function() { },
    "get": function() { return new Date().getMilliseconds(); }
  }
});

foo(args);

【讨论】:

  • 是的,这或多或少是我在评论中想说的。我还没有尝试过代码,还没有足够的信心把它变成答案:)
【解决方案2】:

不,这是不可能的。 args 数组被转换为 apply 中各个值的列表,然后这些值本身作为参数传递。

函数参数永远不会表现出 getter 功能。有some horrible hacks 可以使某个范围内的标识符充当getter/setter,但你永远不应该这样做,而且无论如何你都需要在函数内部这样做。

最好的办法是使用 xy 参数的函数,并在 foo 内显式调用它们。

【讨论】:

    猜你喜欢
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多