Javascript 设置数组索引属性时调用`Object.prototype` setter的原因
给定以下代码:Javascript 设置数组索引属性时调用`Object.prototype` setter的原因,javascript,chromium,Javascript,Chromium,给定以下代码: Object.defineProperty(Object.prototype,'0',{//如果我们在'Array.prototype'上定义,其行为将类似` 对,, get:function(){ log('prototype getter accessed'); 返回此[''u 0'];//允许继续测试 }, 设置:功能(v){ log('prototype setter accessed'); console.log('setValue',v); this[''u 0']
Object.defineProperty(Object.prototype,'0',{//如果我们在'Array.prototype'上定义,其行为将类似`
对,,
get:function(){
log('prototype getter accessed');
返回此[''u 0'];//允许继续测试
},
设置:功能(v){
log('prototype setter accessed');
console.log('setValue',v);
this[''u 0']=v;//参见上面的getter
}
});
log('creating array with 0 index pre-set');
变量a=['a'];
var b=[];
log('push to empty array to set 0 index');
b、 推动('b');
var c=[];
log('直接在空数组上设置0索引');
c[0]=‘c’;
变量d=['d'];
log('直接在非空数组上设置0索引');
d[0]=‘dd’代码>
。作为控制台包装器{
最大高度:100%!重要;
}
这一行为符合规范,尽管看起来Chrome基本上是靠自己来实现的(Firefox和IE11没有)。这里的关键是,在数组创建过程中设置数组[0]
(您的a
和d
示例)与之后的设置不同(您的b
和c
示例;稍后将详细介绍)。这取决于数组初始值设定项的处理方式
换句话说,当一个项目被添加到数组中(在它已经被创建之后),Chrome会出于某种原因进入原型链,尽管更奇怪的是,不是为了获取属性,而是为了设置它
它也适用于get
;您的代码中没有任何get
s,您将看到的内容将根据您使用get
的数组而有所不同(您将看到getter运行b
和c
,但不会运行a
或d
)。产生这种变化的原因是您在a
和d
上创建了“0”
作为自己的属性,但在b
和c
上,它是一个带有getter/setter的继承属性。如果访问b[0]
,我们会看到getter被触发:
Object.defineProperty(Object.prototype,'0',{//如果我们在'Array.prototype'上定义,其行为将类似`
对,,
get:function(){
log('prototype getter accessed');
返回此[''u 0'];//允许继续测试
},
设置:功能(v){
log('prototype setter accessed');
console.log('setValue',v);
this[''u 0']=v;//参见上面的getter
}
});
var b=[];
log('push to empty array to set 0 index');
b、 推动('b');
console.log(“访问b[0]”;
console.log(b[0])代码>
。作为控制台包装器{
最大高度:100%!重要;
}
是否使用c['0']
访问此属性?@evolutionxbox:c[0]
和c['0']
访问同一属性。财产名称从来不是真正的数字;c[0]
中的0
被强制为字符串。@T.J.Crowder但是如果使用数组,属性“0”是否与项0不同?@evolutionxbox:不,它不是。标准数组。@evolutionxbox:我认为主要的问题是为什么访问c[0]
不会触发属性getter。答案很有趣(我现在正在写),我想你可以说“数组是对象”,并发现了一个关于继承的getter/setter被自己的属性隐藏的副本,但是+1nonetheless@Bergi:-)谢谢。这并不能解释为什么a
和d
拥有自己的属性,而b
和c
拥有继承的属性。可能还附带了一个关于JSON劫持的问题的链接:-)这对我自己和其他人都是一个有用的答案,因此标记为,但我可能会发布另一篇文章,以便在有机会时更好地阐述我的问题。