gpt4 book ai didi

javascript - 我可以将 Array.prototype.sort 应用于某个具有访问器属性的类数组对象吗?

转载 作者:行者123 更新时间:2023-11-30 20:34:50 25 4
gpt4 key购买 nike

上下文

const impl = Symbol()
class MyArrayLike {
constructor() {
this[impl] = [2, 1]
Object.freeze(this)
}
get 0() { return this[impl][0] }
set 0(value) { this[impl][0] = value }
get 1() { return this[impl][1] }
set 1(value) { this[impl][1] = value }
get length() { return 2 }
}

const xs = new MyArrayLike()
Array.prototype.sort.call(xs) // (A)
console.log(xs[0], xs[1])

在上面的代码中,我希望显示排序后的值 1 2。但是,Chrome 和 Firefox 的结果不同。

  • 在 Firefox 中,它的行为符合预期。不错。
  • 在 Chrome 中,它在 (A) 处引发了 TypeError,因为访问器属性的 thisundefined

规范在这里:https://www.ecma-international.org/ecma-262/8.0/#sec-array.prototype.sort但是英语对我来说很难。

问题

Chrome 没有在 Array.prototype.sort 的访问器属性中给出 this 是不是一个错误?还是设计使然的非特定行为?

最佳答案

这在 Chrome 上不起作用的原因是 Chrome 和其他浏览器在排序调用期间处理 this 的方式。在其他浏览器中,this 仍然是实例。但是,在 Chrome 中,this 指的是 MyArrayLike 原型(prototype),这是定义访问器属性(getter 和 setter)的地方。在原型(prototype)上,impl 属性不存在(它在实例上),这就是结果未定义的原因。

与数组的一个不同之处在于,它们似乎是为实例本身而非原型(prototype)上的每个索引定义属性。您可以通过在数组实例上调用 Object.getOwnPropertyNames() 来对此进行测试。这将返回索引数组和“长度”。另一方面,如果您尝试在类的实例上调用该函数,它会返回一个空数组。

如果您希望您的代码也能在 Chrome 上运行,一种方法是在实例本身上定义属性,如下面的代码片段所示:

var impl = Symbol()
class MyArrayLike {
constructor() {
this[impl] = [2, 1];
Object.defineProperty(this, 0, {
get: function() { return this[impl][0] },
set: function(value) { this[impl][0] = value }
});
Object.defineProperty(this, 1, {
get: function() { return this[impl][1] },
set: function(value) { this[impl][1] = value }
});
Object.defineProperty(this, "length", {
get: function() { return 2; }
});
Object.freeze(this)
}

}

var xs = new MyArrayLike();
Array.prototype.sort.call(xs);
console.log(xs[0], xs[1]);

这是否是错误,可能需要 Chrome 团队进行检查。但是,这也可能只是 Chrome 的实现方式有所不同。

关于javascript - 我可以将 Array.prototype.sort 应用于某个具有访问器属性的类数组对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49952770/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com