对象js代理中的Chrome 52 Object.keys错误?

时间:2016-07-27 14:20:08

标签: javascript google-chrome

从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) 

有没有人遇到过这个问题?有什么建议?猴子补丁?

1 个答案:

答案 0 :(得分:0)

我清理了一下bug测试。我确实在Chrome 51和Chrome 52上运行了这个,行为确实不同。在Chrome 51中,tKeys等于pKeystNames等于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);