代理无法按预期工作

时间:2018-04-07 10:59:39

标签: javascript oop object

最近,我一直在尝试学习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之外没有扩展名:

enter image description here

2 个答案:

答案 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"
}