【问题标题】:In javascript, how "for .. in" statement can have side effect?在javascript中,“for .. in”语句如何产生副作用?
【发布时间】:2019-07-29 03:33:43
【问题描述】:

我想知道for .. in 会有什么副作用?

let arr = [1.1, 2.2];
let obj = {x: 1, y: 1, z: 1};
for(let prop in obj) {
    ...
}

考虑到上面的 sn-p 代码,是否可以在 for .. in 语句中更改不在循环体中的 arr 中的某些元素?

我目前正在分析 JavaScriptCore JIT 编译器,DFG 假设 GetPropertyEnumerator 有副作用,我知道它可以更改 for .. in 语句中的其他对象。
但是,我不知道这怎么可能。
所以我想这是可能的,如果可能的话,我该怎么做。

【问题讨论】:

  • 如果你的对象有getter/proxy,那些可能会产生副作用……虽然那会是愚蠢的getter。但有点不清楚您是尝试改变某些东西还是想要避免隐式改变某些东西。
  • @deceze 只有在访问obj[prop] 时才会调用getter/代理(这将发生在循环体内)?
  • @CertainPerformance 对于 getter 为 true,但代理提供 has trap,它将由循环触发。
  • 正如@CertainPerformance 所说,只有在访问对象成员时才会触发获取器/代理。
  • 问题更新了!

标签: javascript side-effects javascriptcore


【解决方案1】:

我自己找到了这个问题的答案:)
https://github.com/WebKit/webkit/commit/243a17dd57da84426316502c5346766429f2456d
以上提交日志对我很有帮助!

Proxy 对象有一个名为 getPrototypeOf 的成员。
通过使用这个getPrototypeOf,我可以在for .. in 语句的属性查找阶段修改一些对象。

let a = {x: 1, y: 2, z: 3};
a.__proto__ = {xx: 1, yy: 2, zz: 3};

for(let i in a) {
    print(i);
}

以上是一个简单的例子。
for .. in 语句查找 Object a 的属性,然后遵循 a 的 __proto__ 链。
在这种情况下,Proxy 的getPrototypeOf__proto__ 查找的陷阱。
示例如下。

let a = {
  x: 1,
  y: 2,
  z: 3
};
let p = new Proxy(a, {
  getPrototypeOf: function() {
    console.log("getPrototypeOf - side effects can be caused here");
    return {
      a: 1,
      b: 2
    };
  }
});

for (let i in p) {
  console.log(i);
}

【讨论】:

  • 请在此处提供答案的要点。如果没有该链接,则此答案根本不包含任何有用的内容。
  • 感谢您的反馈 :) @deceze
  • 酷!我将您的 print( 调用(尝试打印当前页面)更改为 console.log 调用(记录传递的参数),希望没关系。您还可以为ownKeys 设置陷阱,这可能更简单一些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
  • 2013-07-23
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
相关资源
最近更新 更多