计算属性查找似乎改变了类/子类型

问题描述 投票:0回答:1

给出以下代码(与更大的程序分离):

class Sum extends Number {} {
  const Sum_ = Sum;

  Sum = function(n) {
    return new Sum_(n);
  };

  Sum.prototype = Sum_.prototype;
}

Sum.prototype[Symbol.toStringTag] = "Sum";

const dispatcher = (...args) => args.map(arg => {
  const tag = Object.prototype.toString.call(arg);
  return tag.slice(tag.lastIndexOf(" ") + 1, -1);
}).join("/");

const VALUE = Symbol("VALUE");

const foo = x => y => {
  if (x && x[VALUE] && (VALUE in x))
    x = x(y);

  else if (y && y[VALUE] && (VALUE in y))
    y = y(x);

  return dispatcher(x, y);
};

const bar = x => y => {
  if (typeof x === "function" && (VALUE in x)) // deviates
    x = x(y);

  else if (typeof y === "function" && (VALUE in y)) // deviates
    y = y(x);

  return dispatcher(x, y);
};

console.log("bar:", bar(Sum(2)) (Sum(3))); // "Sum/Sum"
console.log("bar:", bar(Sum(2)) (Sum(3))); // "Sum/Sum"
console.log("foo:", foo(Sum(2)) (Sum(3))); // "Sum/Sum"
console.log("foo:", foo(Sum(2)) (Sum(3))); // "Number/Number"
console.log("bar:", bar(Sum(2)) (Sum(3))); // "Number/Number"

如你所见,foo / bar几乎完全相同。然而,对foo的第一次调用改变了Sum的原型,以便Object.prototype.toString中的dispatcher调用产生不同的标签。

计算属性查找x[VALUE]似乎是导致突变的决定性部分。我不知道这里发生了什么。也许...

  • 问题很明显,但在盯着代码一小时之后,我再也没有机会看到它了
  • 这个突变是由Sum类引起的
  • 这是一个铬/铬相关的bug

据我了解,Sum声明了一个类,并且下面的块作用域创建了一个引用副本,并使用最终使用new调用该类的函数重新绑定类名,以便在调用端可以省略new。但是,我看不出这与突变有什么关系。

javascript google-chrome ecmascript-6 chromium
1个回答
1
投票

是的,这肯定是一个错误。我能写的最小复制案例是

class Sum extends Number {}
Sum.prototype[Symbol.toStringTag] = "Sum";

const VALUE = Symbol("VALUE");

function foo(x) {
  console.log("x.value", x[VALUE]);
  return Object.prototype.toString.call(x);
}

console.log("foo:", foo(new Sum(2))); // "[object Sum]"
console.log("foo:", foo(new Sum(2))); // "[object Number]"

我不知道这里出了什么问题,但我只能建议不要扩展本机原始包装器:-) 我确实提交了https://bugs.chromium.org/p/v8/issues/detail?id=7706文件。

© www.soinside.com 2019 - 2024. All rights reserved.