Дан следующий код (отсоединен от большой программы):
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
классом
- это ошибка, связанная с хромом / хромом
Насколько я понимаю, Sum
объявляет класс, а следующая область видимости блока создает эталонную копию и повторно связывает имя класса с функцией, которая в конечном итоге вызывает класс с new
, так что new
можно опустить на вызывающая сторона. Однако я не вижу, как это связано с мутацией.