最近,我一直在尝试学习javaScript中的元编程。但是,此脚本会写
false
true
当我希望它写两次true
时,到控制台:
var foo = new Proxy({x:20,y:20},{
has: function(target, prop) {
console.log(target.hasOwnProperty(prop)) //false
if(target.hasOwnProperty(prop)){
return true;
}
return false; //gets returned???
}
});
console.log('toString' in foo) //true
注意:人们已回复说它显示false
两次,这是预期的。我使用vanilla Safari,10.1.2获得false
然后true
,除了禁用Flash和Java之外没有扩展名:
答案 0 :(得分:1)
嗯,Safari确实显示false
然后true
非常有趣。 (我可以验证它在iOS v11.2.6上的iOS Safari中也显示了这一点。)in
使用抽象HasProperty操作,该操作使用对象的[[HasProperty]]内部操作你使用它(在你的情况下,代理)。如果您的处理程序返回false
,则steps for the [[HasProperty]] operation for Proxy objects 执行允许结果与您的处理程序返回的结果不同,但是进行此类操作的其他检查不适用你的代码。具体来说:如果has
处理程序作为" own"存在,则不允许toString
处理程序说该属性不存在。目标上的属性和1)该属性不可配置,或2)该对象不可扩展。您的目标对象没有自己的false
属性,因此不适用。所以看起来Safari可能会让这些检查略显错误。查看快照规范ES2015,ES2016和ES2017,自从代理引入后,此行为未发生变化。
FWIW,它应该输出target
两次,因为:
toString
没有名为Object.prototype
的拥有属性(它从console.log(target.hasOwnProperty(prop));
继承),因此{{1}正确显示false
。
由于您的代理会返回hasOwnProperty
的结果(有点间接),console.log('toString' in foo);
也会正确显示false
。
如果您想让has
执行其正常行为,最好的方法是使用Reflect.has
:
var foo = new Proxy({x:20,y:20},{
has: function(target, prop) {
var flag = Reflect.has(target, prop);
console.log(flag); // true
return flag;
}
});
console.log('toString' in foo) // true

......当然,您可以使用in
:
var foo = new Proxy({x:20,y:20},{
has: function(target, prop) {
var flag = prop in target;
console.log(flag); // true
return flag;
}
});
console.log('toString' in foo) // true

答案 1 :(得分:0)
我得到false
两次
var foo = new Proxy({x:20,y:20},{
has: function(target, prop) {
console.log(target.hasOwnProperty(prop))
if(target.hasOwnProperty(prop)){
return true;
}
return false;
}
});
console.log('toString' in foo);
console.log('x' in foo)

如果您运行console.log('x' in foo)
,则会true
两次x
,因为{x:20,y:20}
中存在toString
属性,而Object.prototype
中存在let obj={x:20,y:20};
console.log('x' in obj);//true
console.log('toString' in obj);//true
console.log(Object.getOwnPropertyNames(obj));//['x','y']
console.log(obj.hasOwnProperty('x'));//true
console.log(obj.hasOwnProperty('y'));//true
console.log(obj.hasOwnProperty('toString'));//false
。
这就是为什么
{
"offerId": "3a06d230-5836-44c2-896b-f5bfb6b27a77",
"outlets": {
"storeUuid": "b3da5136-15a4-4593-aabd-4788f7d80f19",
"location": {
"type": "Point",
"coordinates": [
77,
22
]
}
}"startTime": "2018-04-06T08:03:37.954Z",
"endTime": "2018-04-07T07:35:00.046Z"
},
{
"offerId": "3a06d230-5836-44c2-896b-f5bfb6b27a77",
"outlets": {
"storeUuid": "f18a9a9e-539e-4a9e-b313-d947e2ce76de",
"location": {
"type": "Point",
"coordinates": [
77,
22
]
}
},
"startTime": "2018-04-06T08:03:37.954Z",
"endTime": "2018-04-07T07:35:00.046Z"
},
{
"offerId": "e6c1f140-6407-4481-9a18-56789d90f549",
"outlets": {
"storeUuid": "b3cdd08d-f7f5-4544-8279-08489974148c",
"location": {
"type": "Point",
"coordinates": [
77,
22
]
}
},
"startTime": "2018-04-05T12:30:37.954Z",
"endTime": "2018-04-08T12:38:00.046Z"
},
{
"offerId": "e6c1f140-6407-4481-9a18-56789d90f549",
"outlets": {
"storeUuid": "09d6fc18-9d5c-4b4f-8de1-c6f555b8a370",
"location": {
"type": "Point",
"coordinates": [
77,
22
]
}
},
"startTime": "2018-04-05T12:30:37.954Z",
"endTime": "2018-04-08T12:38:00.046Z"
},
{
"offerId": "e6c1f140-6407-4481-9a18-56789d90f549",
"outlets": {
"storeUuid": "bf71e102-9da1-47b5-81e1-98d27f20bcf4",
"location": {
"type": "Point",
"coordinates": [
77,
22
]
}
},
"startTime": "2018-04-05T12:30:37.954Z",
"endTime": "2018-04-08T12:38:00.046Z"
}