Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我可以将Array.prototype.sort应用于某个具有访问器属性的类似数组的对象吗? 上下文_Javascript - Fatal编程技术网

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

Javascript 我可以将Array.prototype.sort应用于某个具有访问器属性的类似数组的对象吗? 上下文,javascript,Javascript,在上面的代码中,我希望显示排序后的值12。然而,Chrome和Firefox的结果是不同的 在Firefox中,它的行为符合预期。很好 在Chrome中,它在(a)处抛出了一个TypeError,因为访问器属性的这个是未定义的 规格如下: 但是英语对我来说很难 问题: Chrome在Array.prototype.sort的访问器属性中没有给出这个,这是一个bug吗?或者这是一种设计上不具体的行为?这在Chrome上不起作用的原因是Chrome和其他浏览器在排序调用期间处理这一行为的方式。在

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

  • 在Firefox中,它的行为符合预期。很好
  • 在Chrome中,它在
    (a)
    处抛出了一个TypeError,因为访问器属性的
    这个
    未定义的
规格如下: 但是英语对我来说很难

问题:
Chrome在Array.prototype.sort的访问器属性中没有给出
这个
,这是一个bug吗?或者这是一种设计上不具体的行为?

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

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

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

var impl=Symbol()
类MyArrayLike{
构造函数(){
这个[impl]=[2,1];
Object.defineProperty(this,0{
get:function(){返回此[impl][0]},
set:function(value){this[impl][0]=value}
});
Object.defineProperty(这个,1{
get:function(){返回此[impl][1]},
set:function(value){this[impl][1]=value}
});
Object.defineProperty(这是“长度”{
get:function(){return 2;}
});
对象。冻结(此)
}
}
var xs=新的MyArrayLike();
Array.prototype.sort.call(xs);

log(xs[0],xs[1])
我发现
这个
不是
未定义的
,但是
这个[impl]
未定义的
在getter
get 0(){返回这个[impl][0]}
。这听起来确实像个bug,
sort
应该正常调用getter/setter。请向Chrome/V8团队报告。但是请注意,“如果[…]名为小于len的非负整数的obj的任何索引属性是访问器属性[…],则排序顺序也是实现定义的”。我猜这是为了处理本质上使属性不可写的getter/setter,但是您应该记住,如果存在getter或setter,则总是允许
sort()
退出(并且什么也不做)。在上报告了这一点,结果证明这也是一个规范问题:
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])