【ES6】阮一峰ES6学习(六) Proxy

这篇具有很好参考价值的文章主要介绍了【ES6】阮一峰ES6学习(六) Proxy。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 前言

es6中全新设计了一个叫Proxy的类型,Proxy这个词的原意是代理,用在这里表示由它来”代理“某些操作,可以译为”代理器“,可以这样理解:在目标对象之前架设一层"拦截",外界对该对象的访问,都必须先通过这层拦截

举个简单的例子

比如茅台酒的代理,有了这个代理,我们就不能直接从茅台公司拿酒,必须通过这个代理

代理说多少钱,就是多少钱,代理说没有就没有

Proxy 代理的是一个对象,这个对象被代理之后,我们就不能直接访问这个对象了,必须通过代理访问。

比如像获取某个属性的值,代理说没有就没有,代理想给你返回啥值就返回啥值

Proxy就是专门为对象设置访问代理器的,无论是读还是写都要经过代理,通过proxy就能轻松监视对象的读写过程。

2. 使用

如何使用Proxy监视对象的读写过程呢?定义一个person对象,对象当中有一个name属性和height属性,然后通过new Proxy的方式为person创建一个代理对象,此时proxy就是为person对象设置的拦截。

Proxy的构造函数需要2个参数,一个是需要代理的目标对象,另一个是代理的处理对象,在这个处理对象中可以通过get()方法监视对象属性的访问,通过set()方法监视对象设置属性的过程

const person={
    name:'zzz',
    height:185
}
const proxy=new Proxy(person,{
    get(){//监视对象属性的访问

    },
    set(){//监视对象设置属性的过程

    }
})

3. Proxy 实例方法

1. get()方法

get方法是用于拦截某个属性的读取操作,可以接受三个参数,依次为 目标对象、属性名和 proxy实例本身 (操作行为所针对的对象),最后一个参数可选

const proxy=new Proxy(person,{
    get(target,propKey){// 目标对象  访问的属性名
        console.log(target,propKey); // {  } , name
    },
    set(){

    }
})
console.log(proxy.name); // zzz

// 第二个例子
var person = {
  name: "张三"
};

var proxy = new Proxy(person, {
  get: function(target, propKey) {
    if (propKey in target) {
      return target[propKey];
    } else {
      throw new ReferenceError("Prop name \"" + propKey + "\" does not exist.");
    }
  }
});

proxy.name // "张三"
proxy.age // 抛出一个错误

【ES6】阮一峰ES6学习(六) Proxy
get()方法正常的逻辑应该是判断代理目标对象中是否存在访问的属性名,存在就返回对应的值,不存在就返回undefined或者一个默认值

get(target,propKey){
    return propKey in target? target[propKey]:'default'
},

//分别打印存在的属性和不存在的属性
console.log(proxy.name); //zzz
console.log(proxy.age); //default

2. set()方法

set()方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为目标对象、属性名、属性值和 Proxy 实例本身,其中最后一个参数可选

set(target,propKey,value){
    console.log(target,propKey,value);
}

proxy.sex='男'

控制台就会打印出写入的属性和属性值
【ES6】阮一峰ES6学习(六) Proxy

set()方法正常的逻辑应该是为代理目标设置指定属性,在设置之前先做一些数据校验,例如属性名为height,那么那么就要判断它的是否是一个数字,不是就抛出错误

set(target,propKey,value){
    if(propKey=== 'height'){ //判断属性名是否为height
        if(!Number.isInteger(value)){//判断是否为整数
            throw new TypeError(`${value} is not an int`)
        }
    }
    target[propKey]=value
}

set方法的第四个参数receiver,指的是原始的操作行为所在的那个对象,一般情况下是proxy实例本身

const handler = {
	set: function(obj, prop, value, receiver) {
		obj[prop] = receiver;
		return true;
	}
}
const proxy = new Proxy({}, handler);
proxy.foo = 'bar';
proxy.foo === proxy;

3. apply()方法

apply方法拦截函数的调用、callapply 操作

接受三个参数,分别是 ==目标对象、目标对象的上下文对象(this) 和 目标对象的参数数组。

var handler = {
	apply(target, ctx, args){
		return Reflect.apply(...arguments);
	}
};

下面代码中,变量pProxy的实例,当它作为函数调用时(p()),就会被apply方法拦截,返回一个字符串。

var target = function(){ return 'I am the target'};
var handler = {
  apply: function(){
    return 'i am the proxy';
  }
}
var p = new Proxy(target, handler);
console.log(p());  // "i am the proxy"

4. 为什么要存在Proxy?

因为在ES6之前,我们使用Object.defineProperty()来设置监听器,来监听对象属性的获取和改写。但是如果其中存在其他的一些操作,我们是无法监测到的,所以为了解决这样一个问题,在ES6中增加了Proxy代理。Proxy可以帮助我们监听对象中的操作。

两者对比

Object.defineProperty

let info = {
  name: 'dmc',
  age: 20
}

Object.defineProperty(info, 'name', {
  get() {
    console.log('get--获取info的name值')
    return 'dl'
  },
  set() {
    console.log('set--设置info的name值')
  }
})

console.log(info.name) // get--获取info的name值   dl
info.name = 'dmc'  // set--设置info的name值

Proxy文章来源地址https://www.toymoban.com/news/detail-415660.html

let info = {
  name: 'dmc',
  age: 20
}

let infoProxy = new Proxy(info, {
  get(target, key) {
    console.log('获取对象属性')
    return target[key]
  },
  set(target, key, newValue) {
    console.log('设置对象属性')
    target[key] = newValue
  }
})

到了这里,关于【ES6】阮一峰ES6学习(六) Proxy的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ES6-2:Iterator、Proxy、Promise、生成器函数...

    打印出的是里面的内容,如果是for in打印出来的是索引,of不能遍历对象 Symbol.iterator是js内置的,可以访问直接对象arr[Symbol.iterator],()调用 对象非线性一般不能迭代 后两个是伪数组,但是是真迭代器接口 类似于数组,但成员的值都是唯一的,没有重复 与数组不同的是set没有

    2024年04月11日
    浏览(51)
  • ES6中Promise、Async/await解决回调地狱、Proxy代理

    1.Promise 作为一些场景必须要使用的一个对象,比如说我们要发送一个请求,但是在发送这个请求之前我们需要以另一个请求返回的结果中的一个数据作为这次请求的参数,也就是说这个请求必须在另一个请求后面,当然我们用setTimeout定时器写一个延时函数也可以,但是当有

    2024年02月12日
    浏览(32)
  • Vue2和vue3中双向数据绑定的原理,ES6的Proxy对象代理和JavaScript的Object.defineProperty,使用详细

    简介: Object.defineProperty大家都知道,是vue2中双向数据绑定的原理,它 是 JavaScript 中一个强大且常用的方法,用于定义对象属性,允许我们精确地控制属性的行为,包括读取、写入和删除等操作; 而Proxy是vue3中双向数据绑定的原理,是ES6中一种用于创建代理对象的特殊对象,

    2024年02月15日
    浏览(46)
  • ES6如何声明一个类?类如何继承?

    引言 在ES6(ECMAScript 2015)中,引入了类(class)的概念,使得JavaScript的面向对象编程更加直观和易于理解。类提供了一种结构化的方式来定义对象的属性和方法,并且支持继承。在本文中,我们将深入探讨如何在ES6中声明一个类以及如何实现类的继承。 1. 声明一个类 在ES6中

    2024年02月08日
    浏览(29)
  • ES6 ~ ES11 学习笔记

    ·课程地址 let 不能重复声明变量(var 可以) let 具有块级作用域,内层变量外层无法访问 let 不存在变量提升(运行前收集变量和函数,提前声明),但是 var 存在变量提升: 不影响作用域链: 案例: 如果在 for 循环中使用了 var 声明 i,那么它会被提升到全局作用域 window

    2024年02月21日
    浏览(49)
  • es6的学习

    ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。 一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系? 要讲清楚这个问题,需要回顾历史

    2024年02月11日
    浏览(36)
  • ES6学习-Class类

    constructor 构造方法 this 代表实例对象 方法之间不需要逗号分隔,加了会报错。 类的数据类型就是函数,类本身就指向构造函数。 类的所有方法都定义在类的 prototype 属性上面 类的内部所有定义的方法,都是不可枚举的(non-enumerable) ES6类内部定义的方法不可枚举;ES5可以

    2024年02月14日
    浏览(31)
  • js数组学习(ES6+)

    js(ES6+)数组学习 1.Array.prototype.forEach(fn) 遍历数组,传一个函数,每次遍历会运行该函数 2.Array.prototype.map(fn) 数组映射,传入一个函数,映射数组中的每一项,不会改动原数组,然后返回一个新的数组! 3.Array.prototype.filter(fn) 数组筛选,传入一个函数,仅保留满足条件的项。不

    2024年02月12日
    浏览(42)
  • ES6学习-module语法

    CommonJS模块 ES6模块 这种加载称为“编译时加载”或者静态加载 静态加载带来的各种好处 效率要比 CommonJS 模块的加载方式高。 能进一步拓宽 JavaScript 的语法,比如引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。 不再需要 UMD 模块格式了,将来服务器

    2024年02月13日
    浏览(34)
  • 【ECMAScript】ES6-ES11学习笔记

    注意事项 代码中的注释有笔记如 有一些错误示范代码,为了代码整体可运行,将其注释如 当代码有输出是,通常将输出放在对应代码下一行,并注释如下 1.声明变量 2.定义常量 3.解构赋值 4.模板字符串 5.简化对象写法 6.箭头函数 箭头函数适合与this无关的回调,定时器,数

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包