当前位置: 首页 > news >正文

福州做网站外包团队网页设计和网站建设

福州做网站外包团队,网页设计和网站建设,中国建设银行威海分行网站,自建房设计图软件app代理与反射 es6新增了代理和反射特性&#xff0c;这两个特性为开发者提供了拦截并向基本操作嵌入额外行为的能力。 代理基础 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta charset"UTF-8"&g…

代理与反射

es6新增了代理和反射特性,这两个特性为开发者提供了拦截并向基本操作嵌入额外行为的能力。

代理基础

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Title</title></head><body><h2>代理与反射</h2></body><script>const target = {id: 'target'}const handle = {}const proxy = new Proxy(target,handle)console.log(proxy.id)console.log(target.id)</script>
</html>

代理是目标对象的抽象。 所以直接操作代理和直接操作对象,所操作的值都会映射到代理对象上。

代理对象每次执行某个操作(读属性、写属性、定义新属性、查询原型、把它作为函数调用)时,它只会把相应操作发送给处理器对象或目标对象。

Proxy构造器接收两个参数,目标对象处理器对象。如果处理器对象上存在对应方法,代理就调用该方法执行相应操作。如果处理器对象上不存在对应方法,则代理就在目标对象上执行基础操作。

在这里插入图片描述

定义捕获器

使用代理的主要目的是可以定义捕获器。当定义捕获器后,在代理对象上调用基本操作时(比如新增、删除、修改),代理可以在运行这些操作之前调用捕获器,从而拦截并修改相应的行为。

下面看一个例子

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Title</title>
</head>
<body><h2>代理与反射</h2>
</body>
<script>const target = {id: 'target'}const handle = {get(){console.log('捕获器运行')return '这是一个捕获器'}}const proxy = new Proxy(target,handle)console.log(proxy.id)console.log(target.id)
</script>
</html>

在这里插入图片描述

在访问代理对象的属性时,会出发get操作(捕获器函数),但是在原始对象上操作是不会触发的。否则就应该打印两次了。

捕获器函数可以接收三个参数,分别是目标对象,要查询的属性以及代理对象。

那如果我们想在捕获函数内部调用原始对象上的行为呢?Reflect对象为我们提供了这个能力。

下面看一个例子

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Title</title>
</head>
<body><h2>代理与反射</h2>
</body>
<script>const target = {foo: 'bar'}const handle = {get(){return Reflect.get(...arguments)}}const proxy = new Proxy(target,handle)console.log(proxy.foo)console.log(target.foo)
</script>
</html>

在这里插入图片描述

可以看到值是一样的,那么我们利用这个属性就可以在操作对象时给对象的属性添加一些额外的东西,比如

const target = {foo: 'bar'
}
const handle = {get(){return Reflect.get(...arguments) + '帅'}
}
const proxy = new Proxy(target,handle)
console.log(proxy.foo)
console.log(target.foo)

在这里插入图片描述

捕获器的一些限制

在使用捕获器时,需要遵守"捕获器不变式"。原因是因为:如果一个捕获器不遵守捕获器不变式,可能会出现过于反常的行为! 下面来看一个例子:

如果目标对象有一个不可配置且不可写的数据属性,那么在捕获器返回一个与该属性不同的值时,会抛出TypeError

const target = {}
Object.defineProperty(target,'foo',{// 不可配置configurable: false,// 不可写writable: false,value: 'bar'
})
const handle = {get(){return Reflect.get(...arguments) + '帅'}
}
const proxy = new Proxy(target,handle)
console.log(proxy.foo)
console.log(target.foo)

在这里插入图片描述

那捕获器函数返回一个一样的值呢?
在这里插入图片描述

实测返回一样的值不会报错。

撤销代理

很简单,调用一个revocable方法。有想要了解具体的可以看看MDN的介绍。

Proxy.revocable() - JavaScript | MDN

看一段代码就知道怎么使用了

const target = {}
Object.defineProperty(target,'foo',{// 不可配置// configurable: false,// // 不可写// writable: false,value: 'bar'
})
const handle = {get(){console.log('运行')return Reflect.get(...arguments)}
}
const proxy = new Proxy(target,handle)
console.log(proxy.foo)
console.log(target.foo)
const {proxy:proxy1,revoke} = Proxy.revocable(target,handle)
proxy1.foo
revoke()
proxy1.foo

在这里插入图片描述

代理的不足
  1. this指向问题

  2. 代理与内部槽位

    1. 有些js内置类型可能会依赖内部槽位进行一些方法的调用,而代理对象是无法访问到这些方法的,就会导致出错。
const target = new Date()
const proxy = new Proxy(target,{})
console.log(proxy instanceof Date)
proxy.getDate()

输出结果:
在这里插入图片描述

反射

Reflect对象是一个内置的对象,不可以使用new运算符进行实例化,它可以用自己的方法代替原生的操作对象。就是有一个人和你一模一样,你可以不用亲自做一些事情,这个人就帮你做了。

来看一下例子:

const target = {foo: 'bar'
}
delete target.foo
console.log(target)

这是我们如果想要删除对象上的某个属性,采取的一种做法。

来看下反射如何做

const target = {foo: 'bar'
}
Reflect.deleteProperty(target,'foo')
console.log(target)

在这里插入图片描述

在学习过程中我是有一个疑惑的,为什么JS会出现反射呢? 其实它是为了跟Proxy进行配合。

Proxy可以代理对象的一些操作,比如增加、删除、修改。想一下这个场景:如果Proxy代理了新增操作,然后最后想调用原生的赋值方法,该怎么做?

  1. 自己手动实现一个。
const target = {foo: 'bar'
}
let proxy1 = new Proxy(target,{get(target, p, receiver) {console.log('当前值为::',target[p])return target[p]}
})
console.log(proxy1.foo)

在这里插入图片描述

  1. 使用反射
const target = {foo: 'bar'
}
let proxy1 = new Proxy(target,{get(target, p, receiver) {console.log('当前值为::',target[p])return Reflect.get(target,p,receiver)}
})
console.log(proxy1.foo)

在这里插入图片描述

我们无需关心原来操作的实现逻辑,只需要关心我们要为某个操作添加的逻辑即可,原来的逻辑反射会替我们做到。

所以反射的Api是和Proxy捕获器的api一一对应的,当我们想要调用原生操作时,直接使用反射提供的api即可。

总结

从宏观来看,代理是真实JS对象的透明抽象层。在遵循捕获器不变式的前提下,代理可以定义捕获器,可以拦截大部分JS的基本操作和方法。从而增强这些操作。 例如实现装饰器。

反射则封装了一整套与捕获器拦截的操作相对应的方法。可以把反射API看作一套基本操作,包含绝大部分JS对象的API基础。

http://www.yayakq.cn/news/522866/

相关文章:

  • 云主机 网站 多个二级域名 seo优化微信网站建设协议
  • 做视频在哪个网站找素材海报模板在线制作免费无水印
  • 网站产品要如何做详情深圳最好的网站开发公司电话
  • 有专门做预算的网站没成都定制网页设计公司
  • 东台网站建设服务商怎么看别人网站是哪里做的
  • 用ul做的网站为何浮动不上去荆门网站建设电话咨询
  • 怎么自己弄一个网站哪个网站可以免费做国外
  • 网站建设的架构设计苏州网站建设行业
  • html5网站是用什么软件做的中小企业网站建设与推广
  • 做网站就wordpress导航栏去掉
  • 多少钱 网站建设wordpress设置自定义就出现404
  • 传统网站设计的缺点网站主动服务方案
  • 做外贸找生意上哪个网站网站开发与设计总结
  • 公司网站上传不了图片沈阳刚刚发布的公告
  • 建设一个自己的网站外贸网站首页
  • 佛山顺德网站建设公司中国建设银行在网站怎么签约
  • 希音电商网站Wordpress网站能做seo吗
  • 视频网站能备案吗php网站建设心得体会
  • 网站推广文案个人网站空间大小
  • 郑州房地产网站建设东营网站建设专业定制
  • 合肥网站建设市场怎样建设个自己的网站
  • 密云建设网站带动画引导的网站
  • 网站开发流行开原铁岭网站建设
  • 专门做招商的网站是什么大气网站模板免费下载
  • 如何建设国外的网站wordpress生成海报分享
  • 地产公司做网站维护写代码么6中国域名注册
  • 服务器租用网站免费域名网站黄
  • 预约网站如何自己做让家里的电脑做网站服务器
  • 网站后台登陆不了建筑工程知识零基础
  • 东铁匠营网站建设财经网站建设方案