范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

ReflectProxy的理解为什么会有Reflect的出现Proxy的原理

  一、Reflect
  ES6 提供了一个全新的选择 API-Reflect,Reflect 和 Proxy 是相对的,我们可以用 Reflect 操作对象。
  1.1 Reflect 存在的意义1)将 Object 对象一些内部的方法,放到 Reflect 对象上。比如 Object.defineProperty
  现阶段这些方法存在于 object 和 Reflect 对象上,未来只存在于 Reflect 对象上。
  意义:也就是说,从 Reflect 对象上可以拿到语言内部的方法。 2)操作对象出现报错返回 false
  比如:Object.defineProperty(obj,name,desc) 在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj,name,desc)则会返回 false,这样会更合理一些。 // 旧写法 try {   Object.defineProperty(target, property, attributes); } catch (err) {   //failure }  // 新写法 if (Reflect.defineProperty(target, property, attributes)) {   //success } else {   //failure }3)让操作对象的编程变为函数式编程
  说明:老写法有的是命令式编程,比如下面这个例子 // 老写法 "assign" in Object; // true  // 新写法 Reflect.has(Object, "assign"); //true4)保持和 Proxy 对象的方法一一对应
  说明:Reflect 对象的方法与 Proxy 对象的方法一一对应,只要是 Proxy 对象的方法,就能在 Reflect 对象上找到对应的方法。 Proxy(target, {   set: function (target, name, value, receiver) {     var success = Reflect.set(target, name, value, receiver);     if (success) {       console.log("property" + name + "on" + target + "set do " + value);     }     return success;   }, });
  这就让 Proxy 对象可以方便地调用对应的 Reflect 方法,完成默认行为,作为修改行为的基础。也就是说,不管 Proxy 怎么修改默认行为,你总可以在 Reflect 上获取默认行为。
  综上所述:Reflect 对象有 4 个意义: 从 Reflect 对象上可以拿到语言内部的方法。 操作对象出现报错时返回 false 让操作对象都变为函数式编程 保持和 proxy 对象的方法一一对应 1.2 Reflect 常用 API
  静态方法
  Reflect 一共有 13 个静态方法
  它可以一部分是原来在 Object 上的方法,将它转移到了 Reflect 上,并做了小改动,让方法更加合理。 Reflect.defineProperty(target,name,desc)与 Object.defineProperty(target,name,desc)类似,当时对象无法定义时,Object.defineProperty 会报错,而 Reflect.defineProperty 不会,它会返回 false,成功时返回 true,如果不是对象还是会报错。 Reflect.getPrototypeOf(target) 与 Object.getPrototypeOf 一样,返回指定的对象的原型。 Reflect.setProtoTypeOf(target,prototype) 和 Object.setPrototypeOf(target,prototype) 一样,它将指定对象的原型设置为另一个对象。 Reflect.getOwnPropertyDescriptor(target,name)和 Object.getOwnPropertyDescriptor(target,name) 一样,如果在对象中存在,则返回给定的属性的属性描述符。 Reflect.isExtensible(target) 与 Object.isExtensible(target) 类似,判断一个对象是否可扩展(是否可以在它上面添加新的属性),它们的不同点是,当参数不是对象时(原始值),Object 将它强制转换为一个对象,Reflect 直接报错。 Reflect.preventExtensions(target) 与 Object.preventExtensions(target) 类似,阻止新属性添加到对象,不同点和上一条一样。 Reflect.apply(target,thisArg,args)与 Function.prototype.apply.call(fn,obj,args) 一样 Reflect.ownKeys(target) 与 Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)) 一样,返回一个包含所有自身属性(不包含继承属性)的数组。
  另一部分是将原来操作符的功能,变成函数行为 Reflect.has(target,name) 与 in 操作符一样,让判断操作都变成函数行为 Reflect.deleteProperty(target,name) 与 delete 操作符一样,让删除操作变成函数行为,返回布尔值代表成功或者失败 Reflect.construct(target,args[,newTarget]) 与 new 操作符一样,target 构造函数,第二参数是构造函数的参数类数组,第三参数是 new.target 的值。 Reflect.get(target,name[,receiver]) 与 Obj[key] 一样,第三个参数是要取值的 key 部署了 getter 时,访问其函数的 this 绑定为 receiver 对象。 Reflect.set(target,name,value[,receiver]) 设置 target 对象的 key 属性等于 value,第三个参数和 set 一样。返回一个布尔值。 // 老写法 "assign" in Object; // true // 新写法 Reflect.has(Object, "assign"); // true  // 老写法 Function.prototype.apply.call(Math.floor, undefined, [1.75]); // 1 // 新写法 Reflect.apply(Math.floor, undefined, [1.75]); // 1  // 旧写法 delete myObj.foo; // 新写法 Reflect.deleteProperty(myObj, "foo");  // new 的写法 const instance = new Greeting("张三"); // Reflect.construct 的写法 const instance = Reflect.construct(Greeting, ["张三"]);  // 旧写法 Object.defineProperty(MyDate, "now", {   value: () => Date.now(), }); // 新写法 Reflect.defineProperty(MyDate, "now", {   value: () => Date.now(), });  Reflect.get(1, "foo"); // 报错 Reflect.get(false, "foo"); // 报错 Reflect.set(1, "foo", {}); // 报错 Reflect.set(false, "foo", {}); // 报错  var myObject = {   foo: 1,   bar: 2,   get baz() {     return this.foo + this.bar;   }, };  var myReceiverObject = {   foo: 4,   bar: 4, };  Reflect.get(myObject, "baz", myReceiverObject); // 8
  ES6 为 new 命令引入了一个new.target属性,该属性一般用在构造函数之中,返回 new 命令作用于的那个构造函数。如果构造函数不是通过 new 命令或Reflect.construct()调用的,new.target会返回 undefined,因此这个属性可以用来确定构造函数是怎么调用的。function Person(name) {   if (new.target === Person) {     this.name = name;   } else {     throw new Error("必须使用 new 命令生成实例");   } }二、Proxy
  Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等),等同于在语言层面做出修改,所以属于一种"元编程"(meta programming),即对编程语言进行编程。
  Proxy 就像在目标对象之间的一个代理,任何对目标的操作都要经过代理。代理就可以对外界的操作进行过滤和改写。
  Proxy 是构造函数,它有两个参数 target 和 handler。
  target是用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
  handler 是一个对象,其属性是当执行一个操作时定义代理的行为函数。 var obj = new Proxy(   {},   {     get: function (target, key, receiver) {       console.log(`getting ${key}`);       return Reflect.get(target, key, receiver);     },     set: function (target, key, value, receiver) {       console.log(`setting ${key}`);       return Reflect.set(target, key, value, receiver);     },   } ); obj.count = 1; // setting count ++obj.count; // getting count setting count 2
  Proxy 只有一个静态方法revocable(target, handler)可以用来创建一个可撤销的代理对象。两个参数和构造函数的相同。它返回一个包含了所生成的代理对象本身以及该代理对象的撤销方法的对象。
  一旦某个代理对象被撤销,它将变的几乎完全不可用,在它身上执行任何的可代理操作都会抛出 TypeError 异常(注意,可代理操作一共有 14 种,执行这 14 种操作以外的操作不会抛出异常)。一旦被撤销,这个代理对象永远不可能恢复到原来的状态,同时和它关联的目标对象以及处理器对象将有可能被垃圾回收掉。调用撤销方法多次将不会有任何效果,当然,也不会报错。 var revocable = Proxy.revocable(   {},   {     get(target, name) {       return "[[" + name + "]]";     },   } ); // revocable => {"proxy":proxy,"revoke":revoke}  var proxy = revocable.proxy; proxy.foo; // "[[foo]]" revocable.revoke(); // 执行撤销方法  proxy.foo; // TypeError proxy.foo = 1; // TypeError delete proxy.foo; // TypeError typeof proxy; // "object" 因为typeof 不属于代理操作
  handler 参数是代理函数对象,它一共支持 13 种拦截函数。和 Reflect 的相同。如果没有定义某种操作,那么这种操作会被转发到目标对象身上。 const proxy = new Proxy(   {},   {     get: function (target, property, receiver) {       return receiver;       // receiver 总是指向原始的读操作所在的那个对象,一般情况下就是 Proxy 实例。     },   } ); proxy.getReceiver === proxy; // true
  如果一个属性不可配置(configurable)且不可写(writable),则 Proxy 不能修改该属性,否则通过 Proxy 对象访问该属性会报错。 const target = Object.defineProperties(   {},   {     foo: {       value: 123,       writable: false,       configurable: false,     },   } );  const handler = {   get(target, propKey) {     return "abc";   }, };  const proxy = new Proxy(target, handler);  proxy.foo; // TypeError: Invariant check failed
  apply 方法拦截函数的调用、call 和 apply 操作。 var target = function () {   return "I am the target"; }; var handler = {   apply: function () {     return "I am the proxy";   }, };  var p = new Proxy(target, handler);  p(); // "I am the proxy"
  defineProperty 方法拦截了 Object.defineProperty 操作。 var handler = {   defineProperty(target, key, descriptor) {     return false;   }, }; var target = {}; var proxy = new Proxy(target, handler); proxy.foo = "bar"; // 不会生效 // defineProperty 方法返回 false,导致添加新属性总是无效。
  注意,如果目标对象不可扩展(non-extensible),则 defineProperty 不能增加目标对象上不存在的属性,否则会报错。另外,如果目标对象的某个属性不可写(writable)或不可配置(configurable),则 defineProperty 方法不得改变这两个设置。
  getPrototypeOf方法主要用来拦截获取对象原型,会拦截以下这些操作: Object.prototype.__proto__ Object.prototype.isPrototypeOf() Object.getPrototypeOf() Reflect.getPrototypeOf() instanceof
  ownKeys 方法用来拦截对象自身属性读取的操作,会拦截以下操作: Object.getOwnPropertyNames() Object.getOwnPropertySymbols() Object.keys() for...in
  通过代理,你可以轻松地验证向一个对象的传值。 let validator = {   set: function (obj, prop, value) {     if (prop === "age") {       if (!Number.isInteger(value)) {         throw new Error("The age is not an integer");       }       if (value > 200) {         throw new Error("The age seems invalid");       }     }     // The default behavior to store the value     obj[prop] = value;   }, }; let person = new Proxy({}, validator); person.age = 100; console.log(person.age); // 100  person.age = "young"; // 抛出异常: Uncaught TypeError: The age is not an integer person.age = 1000; // 抛出异常: Uncaught RangeError: The age seems invalidthis 指向
  虽然 Proxy 可以代理针对目标对象的访问,但它不是目标对象的透明代理,即不做任何拦截的情况下,也无法保证与目标对象的行为一致。主要原因就是在 Proxy 代理的情况下,目标对象内部的 this 关键字会指向 Proxy 代理。 const target = {   m: function () {     console.log(this === proxy);   }, }; const handler = {}; const proxy = new Proxy(target, handler); target.m(); // false proxy.m(); //trueconst target = new Date(); const handler = {}; const proxy = new Proxy(target, handler);  proxy.getDate(); // TypeError: this is not a Date object.  // getDate 方法只能在Date对象实例上面拿到, // 如果this不是Date对象实例就会报错。 // 这时,this绑定原始对象,就可以解决这个问题 const target = new Date("2021-07-28"); const handler = {   get(target, prop) {     if (prop === "getDate") {       return target.getDate.bind(target);     }     return Reflect.get(target, prop);   }, }; const proxy = new Proxy(target, handler); proxy.getDate(); // 28

我的华为P20Pro用了两年现在好卡顿,大家有这种情况吗?感谢您的阅读!华为P20Pro用了两年,现在好卡顿,大家有这种情况吗?曾经我认为华为的这款手机应该是非常具有实力的一款手机,它的影像能力确实打造出了属于华为P系列的特性。包括现在你在手机拍照方面,哪款手机拍照效果最好?拍照功能最好的手机品牌是什么在手机拍照方面,我觉得自己喜欢怎样的画风很重要,一般很喜欢p图,很喜欢用很多美化软件的人,我觉得应该iPhone手机更加合适,iPhone拍摄的画面是比美团骑手女儿患重病饿了么蓝骑士基金援手救助骑手张文广没有想到,他只是尝试给蓝骑士基金发了一份邮件,半个月后就拿到了该基金助的5万元。这笔钱缓解女儿琪琪(化名)骨髓移植术后抗感染治疗阶段的经济压力。还不到40的张文广,近两年财联社时评柔宇科技到底做错了什么?曾被IDG资本中信资本浦发银行等海内外风投共同看好的柔宇科技,日前不断曝出资金链紧张全员欠薪的负面新闻。从跻身全球独角兽榜排行榜的高光,到千余员工声讨欠薪的窘境,不过短短的一年时间手机经常充满电忘记关电源?手把手教你iPhone充满电后自动提醒你每次为iPhone充电时,是不是任由放在一边充电直到有空后才去看手机是否充满电?甚至充满电后常常忘记拔出数据线或关电源?这样手机的电池会很快坏哦!如果你时常为iPhone充电却忘拼了!丰田将斥资350亿美元押注纯电动10年内推30款车型新能源汽车的渗透率越来越高,汽车电动化的潮流势不可挡,对于传统汽车制造商来说,眼下似乎只有两个选择,要么顺势而为,要么被时代抛弃。作为全球最大汽车制造商的丰田(Toyota)似乎刚华尔街的危机中概股回国上市,外资投行争先涌入中国市场滴滴出行本月证实,将从纽约证券交易所退市,并准备在中国香港上市。此举引发了外界的一系列讨论,这是否宣告中国企业在纽约长期丰厚利润的上市交易即将结束,以及如果香港成为中国最热门初创企元旦换新机的注意,这几款手机高价低配!不要买马上就要元旦了,很多小伙伴都想换新机,现在手机都做得不错,但这几款手机高价低配,小伙伴们不要买第一iPhone12iPhone12的销量并不差,甚至在当时成为了第一季度最畅销的手机传iPhoneSE3即将试产!价格预计2000多你会动心吗?手机中国新闻如果没有意外,在iPhone13系列之后,iPhoneSE3将会在明年春季发布。在此之前,该机已经有了试产的消息。12月20日,据市场消息,苹果最近就会对iPhoneS该不该抄底腾讯好的股票不怕跌,跌出来的都是机会在即时通信领域,腾讯一直是处于垄断地位,前有QQ后有微信,互联网入口被牢牢把控。反垄断只是暂时的。对于腾讯更多的威胁可能来自VRAR领域,新的技术带iPhoneSE3开始生产,阉割版苹果A153GB运行内存苹果公司在2016年推出了第一款SE系列智能手机iPhoneSE,这款机器搭载和iPhone6s系列一样的苹果A9芯片,同时也采用了当时最先进的Nvme协议的存储介质,因此这款机器
OCR文字识别软件如何识别图片?哪款比较好?既然推荐,当然要给大家推荐最值得入手的OCR软件!普通的OCR软件实现图片中的信息识别进阶的OCR软件实现多种文件格式的信息识别高阶的OCR软件实现除了识别信息外,还能对信息进一步如何看待华为即将发布的WATCHGT3Pro支持海洋潜水?对这款产品你还有哪些期待?简单回答。举个例子,GT2系列后面新增的Pro或者ECG其实算是失败产品,新增一些小众的功能,还比如跑步专用runner版本,都卖得很差,价格还高。这次什么海洋潜水什么高山滑雪,都怎么清洗洗衣机里的污垢?因衣物比较脏怕洗不干净,就多加点洗衣精,造成洗衣精没有完全溶解残留在里面,久了洗衣机就又脏又臭。也有些人非常喜欢先浸泡衣物,然后在进行清洗,不惜浸泡到天荒地老的给他泡下去,说这样才乌克兰男子用苹果AirPods定位俄罗斯军队电子发烧友网报道(文吴子鹏)近日,一乌克兰男子宣称自己放置在家里的苹果AirPods耳机于俄乌战争期间在家中丢失了,通过耳机自带的设备跟踪功能,他一步步定位了俄罗斯军队的动向,目前芯片供应商台积电的苹果业务预计今年将增长近25据DigiTimes报道,芯片供应商台积电的苹果业务预计今年将增长近25,因为向苹果芯片的过渡接近完成,两家公司的关系更加紧密。据消息人士向DigiTimes透露,苹果预计台积电将助力发行全球首个月壤数字藏品百度拓展多元化数字藏品开发彭思雨中国证券报中证网中证网讯(记者彭思雨)4月24日,2022年中国航天日线上启动仪式举行,一首AI编曲版东方红拉开航天日序幕。在此期间,探月工程重磅发布了全球首个月壤数字藏品,VIVOX80系列手机抢先看X80搭载联发科天玑90005GSoCLPDDR5丨UFS3。1164。95mm75。23mm8。38。78mm6。78英寸AMOLED居中打孔曲屏,分辨率24001080,120三款大跳水的旗舰手机哪一款更值得购买?早买早享受,晚买享折扣有想换手机的朋友吗?给大家分享几款性价比高的安卓手机。第一款红米K40红米K系列一直是干翻小米的存在,性价比拉到极致,去年火爆一年的红米K40更是如此,最大的余承东不听劝告?杨元庆好言相劝,华为依然入局了一开始组装电脑时,许多对手销量碾压,联想都没有退缩过现在,联想电脑销量世界第一,更没有什么好害怕的了!2019年那场联想全球誓师大会期间,杨元庆如此回应了来自市场方面的竞争。一是联从iPhone12换到RedmiK50Pro,我回不去了,原因主要有4点从iPhone8开始,每一年都会更换新iPhone,原因是我觉得苹果每年都在变强,但是近两年的苹果让我感觉到在挤药膏,尤其是今年的iPhone13相对于去年的iPhone12来讲,6000mAh超大容量手机来了,8GB128GB双屏5G,价格亲民春日生活打卡季可能很多人都不知道Unihertz手机,但它在海外可是很有市场。它由一群充满激情的设计师和工程师组成的,专注于智能手机领域的手机品牌。Unihertz也是一个非常有创