资讯专栏INFORMATION COLUMN

ECMAScript 6入门Proxy与Reflect(上)

DevTTL / 2410人阅读

摘要:与学习的新语法糖既能学习到新东西,又能使得自己的代码更加优雅,逼格更高,爽与之间的运用就是对对象的操作触发的拦截是对对象进行代理,通过生成的对象间接操作原本对象,最常见的就是与语法形式是需要操作的对象,而是包含操作对象的一些方法的对象是能够

Proxy与Reflect

学习es6的新语法糖既能学习到新东西,又能使得自己的代码更加优雅,逼格更高,爽
proxy与Reflect之间的运用就是Reflect对对象的操作触发Proxy的拦截

Proxy是对对象进行代理,通过proxy生成的对象间接操作原本对象,最常见的就是get与set;语法形式var proxy = new Proxy(target, handler); target是需要操作的对象,而handler是包含操作target对象的一些方法的对象

Reflect是能够更加优雅的使用Object的相关方法

学习API

get

proxy: get(target, propKey, receiver)=>依次为目标对象、属性名和 proxy 实例本身(严格地说,是操作行为所针对的对象),其中最后一个参数可选。

let obj = {
    a: "foo",
    b: "Proxy",
    foo: ""
 }
let proxy = new Proxy(obj, {
    get (target, proKey, receive) {
      console.log(target === obj)     //true
      return "当对proxy进行取值操作时会触发这个get函数"
      
    }
 })

ps:proxytarget进行了代理,target就是obj对象,receive用于规定this到底指向哪个对象,

proxy.foo   //当对proxy进行取值操作时会触发这个get函数

上面这种情况并没有改变this的,所以console.log(receive === proxy) //true
Reflect也有get方法:Reflect.get(target, prokey, receive)

Reflect.get(proxy, "foo") //同上没有this的指向
let newobj = {
    foo: "this指向将改变"
}
Reflect.get(proxy, "foo", newobj)  //foo = console.log(receive === proxy)  //true

所以对Reflect.get的第三个参数进行赋值将带入带proxy的get的第三个参数中

set

与get类似,这个是赋值时会触发set方法
proxy: set(target, propKey, value, receiver)

  let obj = {}
  let newobj = {
    a: "123"
  }
  let proxy = new Proxy(obj, {
    set (target, proKey, value, receive) {
      return target[proKey] = `当对proxy进行赋值操作时会触发这个set函数${value}`
      
    }
  })
  proxy.a = 666      //receive === proxy  true
  Reflect.set(proxy, "a", 888)          //receive === proxy  true
  Reflect.set(proxy, "a", 888, newobj)  //receive === newobj  true

apply

proxy的apply:apply(target, object, args)

  let twice = {
    apply (target, ctx, args) {
      console.log(ctx)    //undefined
      return Reflect.apply(...arguments);
    }
  }
  function sum (left, right) {
    this.num = 888  /如果ctx没有传入或者传入null,则会进行window.num = 888的赋值
    return left + right + this.nm
  }
  let obj = {
   nm: 666
  }
  var proxy = new Proxy(sum, twice);
  console.log(proxy(1, 2)) // 6
  console.log(proxy.apply(obj, [7, 8]))  //ctx则为obj,并改变return

执行流程:proxy触发函数调用,执行apply的方法,将参数自动带入,target就是sum函数,ctx没有传入为undefined,args1, 2,接下来将全部参数带入执行Reflect.apply

has

has比较简单,是对对象进行in运算,判断该属性是否存在对象中,可以是自身也可以是原型链上,不管是否可遍历

construct

在构造函数new时触发,

  var p = new Proxy(function () {}, {
    construct: function(target, args, newTarget) {
      console.log("called: " + args.join(", "));
      console.log(newTarget === p)
      return { value: args[0] * 10 };
    }
  });

  console.log((new p(1)).value)
  //等价于下面,Reflect.construct(target, args), args必须是数组
  console.log(Reflect.construct(p, [1]))

ownKeys

返回对象中自身的所有属性,当然具体还是取决于return 什么内容;

触发条件:
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
for...in循环
let target = {
  a: 1,
  b: 2,
  c: 3,
  [Symbol.for("secret")]: "4",
};

Object.defineProperty(target, "key", {
  enumerable: false,
  configurable: true,
  writable: true,
  value: "static"
});

let handler = {
  ownKeys(target) {
    return ["a", "d", Symbol.for("secret"), "key"];
  }
};

let proxy = new Proxy(target, handler);
console.log(Object.keys(proxy))    //自动过滤symbol,不存在的属性,不可遍历的属性
console.log(Reflect.ownKeys(proxy)) //返回handler中return的值

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100585.html

相关文章

  • 【资源集合】 ES6 元编程(Proxy & Reflect & Symbol)

    摘要:理解元编程和是属于元编程范畴的,能介入的对象底层操作进行的过程中,并加以影响。元编程中的元的概念可以理解为程序本身。中,便是两个可以用来进行元编程的特性。在之后,标准引入了,从而提供比较完善的元编程能力。 导读 几年前 ES6 刚出来的时候接触过 元编程(Metaprogramming)的概念,不过当时还没有深究。今天在应用和学习中不断接触到这概念,比如 mobx 5 中就用到了 Pr...

    aikin 评论0 收藏0
  • ECMAScript6(12):ProxyReflect

    摘要:返回一个布尔值拦截操作符,返回一个布尔值拦截操作符,返回一个布尔值拦截遍历器,返回一个遍历器拦截,返回一个布尔值拦截,返回一个数组。 Proxy 对象 Proxy 用来修改某些默认操作,等同于在语言层面做出修改。所以属于一种元编程(meta programming), 即对编程语言进行编程。字面理解为Proxy代理了某些默认的操作。其使用格式如下: var proxy = new Pr...

    habren 评论0 收藏0
  • 从ES6重新认识JavaScript设计模式(五): 代理模式和Proxy

    摘要:此时,链家起到的作用就是代理的作用。验证代理构造函数第二个参数中的方法,可以很方便的验证向一个对象的传值。 1 什么是代理模式 showImg(https://segmentfault.com/img/remote/1460000015800706?w=1262&h=464); 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理...

    verano 评论0 收藏0
  • [译] ES6 学习笔记:关于 ES2015 特性的详细概述

    摘要:将转换成常见的使用实现的基于迭代器的迭代。处停止迭代器基于鸭子模型接口这里使用语法仅仅为了说明问题使用支持为了使用迭代器属性需要引入。生成器是迭代器的子类,包含了附加的与。 原文地址:http://babeljs.io/docs/learn-...本文基于Luke Hoban精妙的文章《es6features》,请把star献给他,你可以在此尝试这些特性REPL。 概述 ECMAScr...

    leoperfect 评论0 收藏0
  • 重温ES6核心概念和基本用法

    摘要:凡是部署了属性的数据结构,就称为部署了遍历器接口。调用这个接口,就会返回一个遍历器对象。 ES6在2015年6月就得以批准,至今已两年了。近一年多以来陆续看过很多ES6的资料,工作项目中也逐步的用上了很多ES6的特性(let,const,promise,Template strings,Class,箭头函数等等),不得不说,这些特性给开发带来了非常多的便利。但是做决定我的ES6知识其...

    philadelphia 评论0 收藏0

发表评论

0条评论

DevTTL

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<