摘要:方法与代理处理程序的方法相同。使用给目标函数传入指定的参数。当然,不用反射也可以读取的值。的例子我们可以理解成是拦截了方法,然后传入参数,将返回值赋值给,这样我们就能在需要读取这个返回值的时候调用。这种代理模式和的代理有异曲同工之妙。
反射 Reflect
当你见到一个新的API,不明白的时候,就在浏览器打印出来看看它的样子。
反射的概念Reflect 是一个内置的对象,它提供可拦截JavaScript操作的方法。方法与代理处理程序的方法相同。Reflect 不是一个函数对象,因此它是不可构造的。
new Reflect() //错误的写法反射的使用
Reflect提供了一些静态方法,静态方法是指只能通过对象自身访问的的方法,这个知识在前面几章讲解过。所有方法的详细解析,前往 Reflect详解 查看。
静态方法列表:这么多静态方法,你需要学会的是如何使用它们。
1、Reflect.apply()
2、Reflect.construct()
3、Reflect.defineProperty()
4、Reflect.deleteProperty()
5、Reflect.enumerate()
6、Reflect.get()
7、Reflect.getOwnPropertyDescriptor()
8、Reflect.getPrototypeOf()
9、Reflect.has()
10、Reflect.isExtensible()
11、Reflect.ownKeys()
12、Reflect.preventExtensions()
13、Reflect.set()
14、Reflect.setPrototypeOf()
静态方法的使用:
demo1:使用Reflect.get()获取目标对象指定key的value。
let obj = { a: 1 }; let s1 = Reflect.get(obj, "a") console.log(s1) // 1
demo2:使用Reflect.apply给目标函数floor传入指定的参数。
const s2 = Reflect.apply(Math.floor, undefined, [1.75]); console.log(s2) // 1进一步理解Reflect
看了上面的例子和方法,我们知道Reflect可以拦截JavaScript代码,包括拦截对象,拦截函数等,然后对拦截到的对象或者函数进行读写等操作。
比如demo1的get()方法,拦截obj对象,然后读取key为a的值。当然,不用反射也可以读取a的值。
再看demo2的apply()方法,这个方法你应该比较了解了,和数组中使用apply不同的是,Reflect.apply()提供了3个参数,第一个参数是反射的函数,后面2个参数才是和数组的apply一致。demo2的例子我们可以理解成是拦截了Math.floor方法,然后传入参数,将返回值赋值给s2,这样我们就能在需要读取这个返回值的时候调用s2。
//数组使用apply const arr = [1, 2, 3] function a() { return Array.concat.apply(null, arguments) } const s = a(arr) console.log(s) // [1, 2 ,3]
其实Reflect的作用和我们下面要讲的Proxy是差不多的。
代理 ProxyProxy这个词相信你已经听过无数遍了,我曾经写过一篇webpack使用代理来拦截指定域的API请求,转发到新的目标URL的文章 webpack中使用proxy。但是注意Proxy和proxy,大小写字母之间是不同的。本章讲的是大写字母开头的Proxy。
语法let p = new Proxy(target, handler);
target:一个目标对象(可以是任何类型的对象,包括本机数组,函数,甚至另一个代理)用Proxy来包装。
handler:一个对象,其属性是当执行一个操作时定义代理的行为的函数。
基础demo:Proxy的demo有很多,我们只分析基础demo,主要看new Proxy({}, handler)的操作,指定目标obj对象,然后handler对象执行get()操作,get()返回值的判断是,如果name是target目标对象的属性,则返回target[name]的值,否则返回37,最后测试的时候,p.a是对象p的key,所以返回a的value,而p.b不存在,返回37。
const obj = { a: 10 } let handler = { get: function(target, name){ console.log("test: ", target, name) // test: {"a":10} a // test: {"a":10} b return name in target ? target[name] : 37 } } let p = new Proxy(obj, handler) console.log(p.a, p.b) // 10 37
这个例子的作用是拦截目标对象obj,当执行obj的读写操作时,进入handler函数进行判断,如果读取的key不存在,则返回默认值。
我们使用一些http-proxy插件或者webpack的时候,有时候需要访问某个api时,跳转到指定的url,这种方式也能解决跨域访问。这种代理模式和Proxy的代理有异曲同工之妙。但是,别混为一体了。
module.exports = { devServer: { proxy: [ { context: "/api/*", //代理API target: "https://www.hyy.com", //目标URL secure: false } ] } }总结
无论是反射还是代理,除了他们使用方法不同之外,他们所作的事情非常相似,都可以理解成拦截某个东西,然后执行某个函数操作,再返回函数操作的结果。
大部分前端在日常业务需求中,几乎很少使用到这2个API,实际使用场景还得在以后的开发中慢慢挖掘。
=> 返回文章目录
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/112352.html
摘要:方法与代理处理程序的方法相同。使用给目标函数传入指定的参数。当然,不用反射也可以读取的值。的例子我们可以理解成是拦截了方法,然后传入参数,将返回值赋值给,这样我们就能在需要读取这个返回值的时候调用。这种代理模式和的代理有异曲同工之妙。 反射 Reflect 当你见到一个新的API,不明白的时候,就在浏览器打印出来看看它的样子。 showImg(https://segmentfault....
摘要:是陷阱函数对应的反射方法,同时也是操作的默认行为。对象外形指的是对象已有的属性与方法的集合,由于该属性验证只须在读取属性时被触发,因此只要使用陷阱函数。无论该属性是对象自身的属性还是其原型的属性。 主要知识点:代理和反射的定义、常用的陷阱函数、可被撤销的代理、将代理对象作为原型使用、将代理作为类的原型showImg(https://segmentfault.com/img/bVbfWr...
摘要:代理和反射的定义调用可常见代替其它目标对象的代理,它虚拟化了目标,所以二者看起来功能一致。代理可拦截引擎内部目标的底层对象操作,这些底层操作被拦截后会触发响应特定操作的陷阱函数。 代理和反射的定义 调用 new Proxy() 可常见代替其它目标 (target) 对象的代理,它虚拟化了目标,所以二者看起来功能一致。 代理可拦截JS引擎内部目标的底层对象操作,这些底层操作被拦截后会触发...
摘要:最近买了深入理解的书籍来看,为什么学习这么久还要买这本书呢主要是看到核心团队成员及的创造者为本书做了序,作为一个粉丝,还是挺看好这本书能给我带来一个新的升华,而且本书的作者也非常厉害。 使用ES6开发已经有1年多了,以前看的是阮一峰老师的ES6教程,也看过MDN文档的ES6语法介绍。 最近买了《深入理解ES6》的书籍来看,为什么学习ES6这么久还要买这本书呢?主要是看到Daniel A...
阅读 1421·2021-09-30 09:57
阅读 1406·2021-09-09 09:33
阅读 2125·2021-09-04 16:40
阅读 1757·2021-09-01 10:50
阅读 3196·2021-09-01 10:31
阅读 2485·2019-08-30 15:56
阅读 2927·2019-08-30 15:44
阅读 3445·2019-08-29 17:29