关注「松宝写代码」,精选好文,每日一题

作者:saucxs | songEagle

一、前言

2020.12.23 日刚立的 flag,每日一题,题目类型不限度,能够是:算法题,面试题,论述题等等。

本文是「每日一题」第 8 题:[每日一题]面试官问:谈谈你对ES6的proxy的了解

往期「每日一题」:

  • 第 7 题[[每日一题]面试官问:for in和for of 的区别和原理?](https://mp.weixin.qq.com/s/Rs...
  • 第 6 题[[每日一题]面试官问:Async/Await 如何通过同步的形式实现异步?](https://mp.weixin.qq.com/s/UA...
  • 第 5 道「每日一题」到底该如何答复:vue数据绑定的实现原理?
  • 第 4 道「每日一题」与面试官手撕代码:如何迷信高效的寻找反复元素?
  • 第 3 道「「每日一题」面试官问你对 Promise 的了解?可能是须要你能手动实现各个个性」
  • 第 2 道[「[每日一题]ES6 中为什么要应用 Symbol?」](https://mp.weixin.qq.com/s/om...
  • 第 1 道「一道面试题是如何引发深层次的灵魂拷问?」

二、什么是Proxy?

Proxy,代理,是ES6新增的性能,能够了解为代理器(即由它代理某些操作)。

Proxy 对象用于定义或批改某些操作的自定义行为,能够在外界对指标对象进行拜访前,对外界的拜访进行改写。

1、Proxy定义

var proxy = new Proxy(target, handler)

new Proxy()示意生成一个 Proxy 实例

  • target:指标对象
  • handler:一个对象,其属性是当执行一个操作时定义代理的行为的函数。

留神:要实现拦挡操作,必须是对 Proxy 实例进行操作,而不是针对指标对象 target 进行操作。

2、proxy拦挡get和set操作

咱们先来看一下proxy拦挡get和set操作,示例代码如下:

let handler = {    get: function(target, key, receiver) {        console.log(`getter ${key}!`)        return Reflect.get(target, key, receiver)    },    set: function(target, key, value, receiver) {        console.log(`setter ${key}=${value}`)        return Reflect.set(target, key, value, receiver)    }}var obj = new Proxy({}, handler)obj.a = 1          // setter a=1obj.b = undefined  // setter b=undefinedconsole.log(obj.a, obj.b) // getter a!// getter b!// 1 undefinedconsole.log('c' in obj, obj.c)    // getter c!// false undefined

3、proxy笼罩组件的原始行为

咱们来看一下,示例代码如下:

let handler = {    get: function(target, key, receiver) {        return 1    },      set: function (target, key, value, receiver) {        console.log(`setting ${key}!`);        return Reflect.set(target, key, value, receiver);      }}var obj = new Proxy({}, handler)obj.a = 5       // setting 5!console.log(obj.a);    // 1

由下面代码看出:Proxy 不仅是拦挡了行为,更是用本人定义的行为笼罩了组件的原始行为。

若handler = {},则代表 Proxy 没有做任何拦挡,拜访 Proxy 实例就相当于拜访 target 指标对象。

三、Proxy handle办法

  • 1、get(target, key, receiver):拦挡 target 属性的读取
  • 2、set(target, key, value, receiver):拦挡 target 属性的设置
  • 3、has(target, key):拦挡 key in proxy 的操作,并返回是否存在(boolean值)
  • 4、deleteProperty(target, key):拦挡 delete proxy[key]的操作,并返回后果(boolean值)
  • 5、ownKeys(target):拦挡Object.getOwnPropertyName(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for ... in循环。并返回指标对象所有本身属性的属性名数组。留神:Object.keys()的返回后果数组中只蕴含指标对象本身的可遍历属性
  • 6、getOwnPropertyDescriptor(target, key):拦挡 Object.getOwnPropertyDescriptor(proxy, key),返回属性的形容对象
  • 7、defineProperty(target, key, desc):拦挡Object.defineProperty(proxy, key, desc)、Object.defineProperties(proxy, descs),返回一个 boolean 值
  • 8、preventExtensions(target):拦挡Object.preventExtensions(proxy),返回一个 boolean 值
  • 9、getPrototypeOf(target):拦挡Object.getPrototypeOf(proxy),返回一个对象
  • 10、isExtensible(target):拦挡Object.isExtensible(proxy),返回一个 boolean 值
  • 11、setPrototypeOf(target, key):拦挡Object.setPrototypeOf(proxy, key),返回一个 boolean 值。如果指标对象是函数,则还有两种额定操作能够被拦挡
  • 12、apply(target, object, args):拦挡 Proxy 实例作为函数调用的操作,比方proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)
  • 13、construct(target, args):拦挡 Proxy 实例作为结构函数调用的操作,比方new proxy(...args)

总共 13 个拦挡办法,上面进行简要举例说明,更多可见阮一峰老师的 《ECMAScript 6 入门》(https://es6.ruanyifeng.com/#d...)

1、get办法和set办法

get办法用于拦挡某个属性的读取操作,能够承受三个参数,顺次为指标对象、属性名和 proxy 实例自身(严格地说,是操作行为所针对的对象),其中最初一个参数可选。

set拦挡 target 属性的设置,能够承受四个参数,顺次为指标对象、属性名、value和 proxy 实例自身(严格地说,是操作行为所针对的对象),其中最初一个参数可选。

let target = {foo: 1}let proxy = new Proxy(target, {    get(target, key, receiver) {        console.log(`getter ${key}!`)        return target[key]    },    set: function(target, key, value, receiver) {        console.log(`setter ${key}!`)        target[key] = value;    }})let obj = Object.create(proxy)console.log(obj.foo) // getter foo!// 1

2、has办法

拦挡 propKey in proxy 的操作,返回一个布尔值。

// 应用 has 办法暗藏某些属性,不被 in 运算符发现var handler = {    has (target, key) {        if (key.startsWith('_')) {            return false;        }        return key in target;    }};var foo = { _name: 'saucxs', name: 'saucxs' };var proxy = new Proxy(foo, handler);console.log('_name' in proxy); // falseconsole.log('name' in proxy); // true

3、ownKeys办法

拦挡本身属性的读取操作。并返回指标对象所有本身属性的属性名数组。具体返回后果可联合 MDN 属性的可枚举性和所有权

  • Object.getOwnPropertyName(proxy)
  • Object.getOwnPropertySymbols(proxy)
  • Object.keys(proxy)
  • for ... in循环
let target = {  _foo: 'foo',  _bar: 'bar',  name: 'saucxs'};let handler = {  ownKeys (target) {    return Reflect.ownKeys(target).filter(key => key.startsWith('_'));  }};let proxy = new Proxy(target, handler);for (let key of Object.keys(proxy)) {  console.log(target[key]);}// "saucxs"

4、apply办法

apply 拦挡 Proxy 实例作为函数调用的操作,比方函数的调用(proxy(...args))、call(proxy.call(object, ...args))、apply(proxy.apply(...))等。

var target = function () { return 'I am the target'; };var handler = {  apply: function () {    return 'I am the saucxs proxy';  }};var proxy = new Proxy(target, handler);proxy();// "I am the saucxs proxy"

更多可见阮一峰老师的 《ECMAScript 6 入门》(https://es6.ruanyifeng.com/#d...)

谢谢反对

1、文章喜爱的话能够「分享,点赞,在看」三连哦。

2、作者昵称:saucxs,songEagle,松宝写代码。「松宝写代码」公众号作者,每日一题,实验室等。一个喜好折腾,致力于全栈,正在致力成长的字节跳动工程师,星辰大海,将来可期。内推字节跳动各个部门各个岗位。

3、长按上面图片,关注「松宝写代码」,是获取开发常识体系构建,精选文章,我的项目实战,实验室,每日一道面试题,进阶学习,思考职业倒退,波及到JavaScript,Node,Vue,React,浏览器,http等畛域,心愿能够帮忙到你,咱们一起成长~

字节内推福利

  • 回复「校招」获取内推码
  • 回复「社招」获取内推
  • 回复「实习生」获取内推

后续会有更多福利

学习材料福利

回复「算法」获取算法学习材料

往期「每日一题」

1、JavaScript && ES6

  • 第 19 题:【每日一题】面试官问:谈谈JS中的 XMLHttpRequest 对象的了解?
  • 第 18 题:【每日一题】面试官问:JS中的 Ajax 跨域与扩大 Comet ?
  • 第 17 题:【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的了解?
  • 第 16 题:【每日一题】面试官问:JS中如何全面进行客户端检测?
  • 第 15 题:【每日一题】面试官问:JS类型判断有哪几种办法?
  • 第 14 题:【每日一题】面试官问:谈谈你对JS对象的创立和引申
  • 第 13 题[[每日一题]面试官问:['1', '2', '3'].map(parseInt)输入,起因,以及延长?](https://mp.weixin.qq.com/s/DJ...
  • 第 12 题[[每日一题]面试官问:JS引擎的执行过程(二)](https://mp.weixin.qq.com/s/CC...
  • 第 11 题[[每日一题]面试官问:JS引擎的执行过程(一)](https://mp.weixin.qq.com/s/Lh...
  • 第 10 题[[每日一题]面试官问:具体说一下JS数据类型](https://mp.weixin.qq.com/s/wm...
  • 第 8 题[[每日一题]面试官问:谈谈你对ES6的proxy的了解?](https://mp.weixin.qq.com/s/8l...
  • 第 7 题[[每日一题]面试官问:for in和for of 的区别和原理?](https://mp.weixin.qq.com/s/Rs...
  • 第 6 题[[每日一题]面试官问:Async/Await 如何通过同步的形式实现异步?](https://mp.weixin.qq.com/s/UA...
  • 第 3 道「「每日一题」面试官问你对 Promise 的了解?可能是须要你能手动实现各个个性」
  • 第 2 道[「[每日一题]ES6 中为什么要应用 Symbol?」](https://mp.weixin.qq.com/s/om...

2、浏览器

  • 第 9 题[[每日一题]requestAnimationFrame不香吗?](https://mp.weixin.qq.com/s/4O...

3、Vue

  • 第 5 道「每日一题」到底该如何答复:vue数据绑定的实现原理?

4、算法

  • 第 4 道「每日一题」与面试官手撕代码:如何迷信高效的寻找反复元素?

5、Http

  • 第 1 道「一道面试题是如何引发深层次的灵魂拷问?」