从Chrome 52开始。如果在代理中调用,Object.keys也显示非可枚举字段。 Chrome 51还可以。 Edge和Firefox也可以。
这是一个愚蠢的测试来展示它。只需在Chrome 52上运行它就会显示错误行为:
var target={};
Object.defineProperty(target,"__observerCallbacks__",{enumerable:false,configurable:true,writable:false,value:['aaaa']});
var ori='';
Object.keys(target).forEach(
function(x){
ori+=x;
}
);
var proxy='';
var p = new Proxy(target, {get:function(target,property)
{
return property;
}
});
Object.keys(p).forEach(
function(x){
//if (window.target.propertyIsEnumerable(x)){
proxy+=x;
//}
}
);
//alert('ori '+ori+' proxy '+proxy);
console.log('ori', ori, 'proxy', proxy)
有没有人遇到过这个问题?有什么建议?猴子补丁?
答案 0 :(得分:0)
我清理了一下bug测试。我确实在Chrome 51和Chrome 52上运行了这个,行为确实不同。在Chrome 51中,tKeys
等于pKeys
而tNames
等于pNames
,但在Chrome 52中,tKeys
等于tNames
,这似乎有问题。
将__observerCallbacks__
更改为其他属性名称似乎无法解决此问题,因此该属性的名称不相关。我建议您向Google提交此错误报告。
另外,当属性名称为value
时,由于某种原因,属性描述符会将["aaaa"]
从"_"
更改为__observerCallbacks__
。我不知道为什么会这样做,但我认为它并不相关,因为它与该属性名称有关。
var target = {};
Object.defineProperty(target, "__observerCallbacks__", {
enumerable: false,
configurable: true,
writable: false,
value: ['aaaa']
});
var tKeys = Object.keys(target);
var tNames = Object.getOwnPropertyNames(target);
var tProps = tNames.map(Object.getOwnPropertyDescriptor.bind(target));
var tValue = target.__observerCallbacks__;
var proxy = new Proxy(target, {
get: function(target, property) {
return property;
}
});
var pKeys = Object.keys(proxy);
var pNames = Object.getOwnPropertyNames(proxy);
var pProps = pNames.map(Object.getOwnPropertyDescriptor.bind(proxy));
var pValue = proxy.__observerCallbacks__;
console.log('target keys:', tKeys);
console.log('target own names:', tNames);
console.log('target property descriptors:', tProps);
console.log('target value:', tValue);
console.log('proxy keys:', pKeys);
console.log('proxy own names:', pNames);
console.log('proxy property descriptors', pProps);
console.log('proxy value:', pValue);