IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> ES6中的代理proxy -> 正文阅读

[JavaScript知识库]ES6中的代理proxy

Proxy:代理器,改变对象的默认访问行为;在对象的访问行为之前增设拦截,通过Proxy实例进行的访问行为都必须经过设置的拦截;在拦截中可以根据需要 设置拦截条件

p()为自定义函数,后文中的p()都是调用这个函数

????????let p = function(){
?? ??? ??? ?console.log(...arguments);
?? ??? ?}

目录

拦截器

一、数组代理

二、对象代理

三、函数代理

四、class代理

五、ES5中的代理


拦截器

拦截器作用
get拦截对象属性的读取,如obj.key,obj['key'],返回属性值
set拦截属性的设置,返回布尔值
has拦截key in obj的操作,返回布尔值
ownKeys

拦截遍历如:

????????for in 循环
?? ??? ?Object.getOwnPropertyNames(obj);
?? ??? ?Object.getOwnPropertySymbols(obj);
?? ??? ?Object.keys(obj);

一、数组代理

1、拦截获取值的操作

2、拦截设置操作,给数组赋值或者添加元素时触发如:arr.push(xxx),arr[0] = xxx

let arr = [1,2,3,4,5];

arr = new Proxy(arr,{

? ? ? ? //如果元素存在返回值,否则返回error

? ? ? ? get(target,prop){//target为代理的对象,此处为数组arr;prop此处为索引

? ? ? ? ? ? ? ? return prop in target ? target[prop] : 'error';

????????},

? ? ? ? //设置值时触发

? ? ? ? set(target,prop,val){

? ? ? ? ? ? ? ? if(typeof val === 'number'){//是数值类型添加,否则报错,

? ? ? ? ? ? ? ? ? ? ? ?target[prop] = val;//可根据实际需要修改条件

????????????????????????return true;

????????????????}else return false;

????????}

})

二、对象代理

1、拦截是否存在如in

????????let age = {
?? ??? ??? ?min:0,
?? ??? ??? ?max:143
?? ??? ?}
?? ??? ?age = new Proxy(age,{
?? ??? ??? ?has(target,prop){
?? ??? ??? ??? ?return prop >= target.min && prop <= target.max;
?? ??? ??? ?}
?? ??? ?})
?? ??? ?p(23 in age);
?? ??? ?p(144 in age);

2、拦截遍历如:

????????for in 循环
?? ??? ?Object.getOwnPropertyNames(obj);
?? ??? ?Object.getOwnPropertySymbols(obj);
?? ??? ?Object.keys(obj);

????????let user = {
?? ??? ??? ?name:"Asia",
?? ??? ??? ?age:23,
?? ??? ??? ?_password:'666'
?? ??? ?}
?? ??? ?user = new Proxy(user,{
?? ??? ??? ?ownKeys(target){

? ? ? ? ? ? ? ? //将对象的所有键中以'_'开头的键过滤掉,此处过滤了密码属性
?? ??? ??? ??? ?return Object.keys(target).filter(key => !key.startsWith('_'));//可根据需要自定义拦截条件
?? ??? ??? ?}
?? ??? ?});
?? ??? ?for(let key in user){
?? ??? ??? ?p(key);
?? ??? ?}

3、拦截某些属性一切操作

????????let u = {
?? ??? ??? ?name:'Asia',
?? ??? ??? ?age:23,
?? ??? ??? ?_password:'666'
?? ??? ?}
?? ??? ?u = new Proxy(u,{
?? ??? ??? ?set(obj,key,val){
?? ??? ??? ??? ?if(key.startsWith('_')){
?? ??? ??? ??? ??? ?throw new Error('不可修改');
?? ??? ??? ??? ?}else{
?? ??? ??? ??? ??? ?obj[key] = val;
?? ??? ??? ??? ?}
?? ??? ??? ?},
?? ??? ??? ?get(obj,key){
?? ??? ??? ??? ?if(key.startsWith('_')){
?? ??? ??? ??? ??? ?throw new Error('不可访问');
?? ??? ??? ??? ?}else{
?? ??? ??? ??? ??? ?return obj[key];
?? ??? ??? ??? ?}
?? ??? ??? ?},
?? ??? ??? ?deleteProperty(obj,key){
?? ??? ??? ??? ?if(key.startsWith('_')){
?? ??? ??? ??? ??? ?throw new Error('不可删除');
?? ??? ??? ??? ?}else{
?? ??? ??? ??? ??? ?delete obj[key];
?? ??? ??? ??? ??? ?return true;
?? ??? ??? ??? ?}
?? ??? ??? ?},
?? ??? ??? ?ownKeys(obj,key){
?? ??? ??? ??? ?return Object.keys(obj).filter(key => !key.startsWith('_'));
?? ??? ??? ?}
?? ??? ?})
?? ??? ?
?? ??? ?try{
?? ??? ??? ?u._password = '000';
?? ??? ?}catch(err){
?? ??? ??? ?p(err.message);
?? ??? ?};
?? ??? ?
?? ??? ?try{
?? ??? ??? ?p(u._password);
?? ??? ?}catch(err){
?? ??? ??? ?p(err.message);
?? ??? ?}
?? ??? ?
?? ??? ?try{
?? ??? ??? ?delete u._password;
?? ??? ??? ?
?? ??? ?}catch(err){
?? ??? ??? ?p(err.message);
?? ??? ?}
?? ??? ?Object.keys(u).forEach(key => p(u[key]));?

三、函数代理

改变函数返回值

????????let sum = (...args) => {
?? ??? ??? ?let sum = 0;
?? ??? ??? ?args.forEach(item => {
?? ??? ??? ??? ?sum += item;
?? ??? ??? ?});
?? ??? ??? ?return sum;
?? ??? ?}
?? ??? ?sum = new Proxy(sum,{
?? ??? ??? ?apply(fn,ctx,args){
?? ??? ??? ??? ?return fn(...args) * 10;
?? ??? ??? ?}
?? ??? ?});
?? ??? ?p(sum(1,2,3));//60
?? ??? ?p(sum.call(null,1,2,3));//60
?? ??? ?p(sum.apply(null,[1,2,3]));//60

四、class代理

对new进行拦截

let User = class{
?? ??? ??? ?constructor(name){
?? ??? ??? ??? ?this.name = name;
?? ??? ??? ?}
?? ??? ?}
?? ??? ?User = new Proxy(User,{
?? ??? ??? ?construct(cls,args,newCls){
?? ??? ??? ??? ?p('construct 正在拦截');
?? ??? ??? ??? ?return new cls(...args);
?? ??? ??? ?}
?? ??? ?});
?? ??? ?p(new User('Asia'));

五、ES5中的代理

Object.definePrototype(obj,属性名,callback);

let obj = {};

let _name = '';

Object.definePrototype(obj,'name',{

? ? ? ? set(val){

? ? ? ? ? ? ? ? _name = val;

????????},

? ? ? ? get(){

? ? ? ? ? ? ? ? return _name;

????????}

})

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 10:40:34  更:2022-07-03 10:41:42 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:06:13-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码