ES6 入门教程 15 Proxy 15.2 Proxy 实例的方法 15.2.10 ownKeys() ~ 15.2.12 setPrototypeOf()

news2025/2/4 5:00:16

ES6 入门教程

ECMAScript 6 入门

作者:阮一峰

本文仅用于学习记录,不存在任何商业用途,如侵删

文章目录

      • ES6 入门教程
      • 15 Proxy
        • 15.2 Proxy 实例的方法
          • 15.2.10 ownKeys()
          • 15.2.11 preventExtensions()
          • 15.2.12 setPrototypeOf()

15 Proxy

15.2 Proxy 实例的方法

拦截方法的详细介绍。

15.2.10 ownKeys()

ownKeys()方法用来拦截对象自身属性的读取操作。具体来说,拦截以下操作。

  • Object.getOwnPropertyNames()
  • Object.getOwnPropertySymbols()
  • Object.keys()
  • for...in循环

下面是拦截Object.keys()的例子。

let target = {
  a: 1,
  b: 2,
  c: 3
};

let handler = {
  ownKeys(target) {
    return ['a'];
  }
};

let proxy = new Proxy(target, handler);

Object.keys(proxy)
// [ 'a' ]

在这里插入图片描述

上面代码拦截了对于target对象的Object.keys()操作,只返回abc三个属性之中的a属性。

下面的例子是拦截第一个字符为下划线的属性名。

let target = {
  _bar: 'foo',
  _prop: 'bar',
  prop: 'baz'
};

let handler = {
  ownKeys (target) {
    return Reflect.ownKeys(target).filter(key => key[0] !== '_');
  }
};

let proxy = new Proxy(target, handler);
for (let key of Object.keys(proxy)) {
  console.log(target[key]);
}
// "baz"

注意,使用Object.keys()方法时,有三类属性会被ownKeys()方法自动过滤,不会返回。

  • 目标对象上不存在的属性
  • 属性名为 Symbol 值
  • 不可遍历(enumerable)的属性
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);

Object.keys(proxy)
// ['a']

在这里插入图片描述

上面代码中,ownKeys()方法之中,显式返回不存在的属性(d)、Symbol 值(Symbol.for('secret'))、不可遍历的属性(key),结果都被自动过滤掉。

ownKeys()方法还可以拦截Object.getOwnPropertyNames()

var p = new Proxy({}, {
  ownKeys: function(target) {
    return ['a', 'b', 'c'];
  }
});

Object.getOwnPropertyNames(p)
// [ 'a', 'b', 'c' ]

在这里插入图片描述

for...in循环也受到ownKeys()方法的拦截。

const obj = { hello: 'world' };
const proxy = new Proxy(obj, {
  ownKeys: function () {
    return ['a', 'b'];
  }
});

for (let key in proxy) {
  console.log(key); // 没有任何输出
}

上面代码中,ownkeys()指定只返回ab属性,由于obj没有这两个属性,因此for...in循环不会有任何输出。

ownKeys()方法返回的数组成员,只能是字符串或 Symbol 值。如果有其他类型的值,或者返回的根本不是数组,就会报错。

var obj = {};

var p = new Proxy(obj, {
  ownKeys: function(target) {
    return [123, true, undefined, null, {}, []];
  }
});

Object.getOwnPropertyNames(p)
// Uncaught TypeError: 123 is not a valid property name

上面代码中,ownKeys()方法虽然返回一个数组,但是每一个数组成员都不是字符串或 Symbol 值,因此就报错了。

如果目标对象自身包含不可配置的属性,则该属性必须被ownKeys()方法返回,否则报错。

var obj = {};
Object.defineProperty(obj, 'a', {
  configurable: false,
  enumerable: true,
  value: 10 }
);

var p = new Proxy(obj, {
  ownKeys: function(target) {
    return ['b'];
  }
});

Object.getOwnPropertyNames(p)
// Uncaught TypeError: 'ownKeys' on proxy: trap result did not include 'a'

上面代码中,obj对象的a属性是不可配置的,这时ownKeys()方法返回的数组之中,必须包含a,否则会报错。

另外,如果目标对象是不可扩展的(non-extensible),这时ownKeys()方法返回的数组之中,必须包含原对象的所有属性,且不能包含多余的属性,否则报错。

var obj = {
  a: 1
};

Object.preventExtensions(obj);

var p = new Proxy(obj, {
  ownKeys: function(target) {
    return ['a', 'b'];
  }
});

Object.getOwnPropertyNames(p)
// Uncaught TypeError: 'ownKeys' on proxy: trap returned extra keys but proxy target is non-extensible

上面代码中,obj对象是不可扩展的,这时ownKeys()方法返回的数组之中,包含了obj对象的多余属性b,所以导致了报错。

15.2.11 preventExtensions()

preventExtensions()方法拦截Object.preventExtensions()。该方法必须返回一个布尔值,否则会被自动转为布尔值。

这个方法有一个限制,只有目标对象不可扩展时(即Object.isExtensible(proxy)false),proxy.preventExtensions才能返回true,否则会报错。

var proxy = new Proxy({}, {
  preventExtensions: function(target) {
    return true;
  }
});

Object.preventExtensions(proxy)
// Uncaught TypeError: 'preventExtensions' on proxy: trap returned truish but the proxy target is extensible

上面代码中,proxy.preventExtensions()方法返回true,但这时Object.isExtensible(proxy)会返回true,因此报错。

为了防止出现这个问题,通常要在proxy.preventExtensions()方法里面,调用一次Object.preventExtensions()

var proxy = new Proxy({}, {
  preventExtensions: function(target) {
    console.log('called');
    Object.preventExtensions(target);
    return true;
  }
});

Object.preventExtensions(proxy)
// "called"
// Proxy {}
15.2.12 setPrototypeOf()

setPrototypeOf()方法主要用来拦截Object.setPrototypeOf()方法。

下面是一个例子。

var handler = {
  setPrototypeOf (target, proto) {
    throw new Error('Changing the prototype is forbidden');
  }
};
var proto = {};
var target = function () {};
var proxy = new Proxy(target, handler);
Object.setPrototypeOf(proxy, proto);
// Error: Changing the prototype is forbidden

上面代码中,只要修改target的原型对象,就会报错。

注意,该方法只能返回布尔值,否则会被自动转为布尔值。另外,如果目标对象不可扩展(non-extensible),setPrototypeOf()方法不得改变目标对象的原型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/21855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法题:SOJ1092: 欧几里得算法

一、BackGroud 在RSA密码体系中,欧几里得算法是加密或解密运算的重要组成部分。它的基本运算过程就是解 x*a1(mod n) 这种方程。 二、The Problem 整个解的过程是这样的,我们用一个例子来说明。 当a=1001 ,n=3837时 方程为 x *…

12 个免费 GIS 数据源介绍:最佳全球栅格和矢量数据集

我们生活在当今的信息时代,每天都被大量的信息包围,就免费的 GIS 数据源而言,它的信息似乎是永无止境的。机器学习、人工智能、区块链、预测分析,所有令人惊叹的技术都将革新商业和社会的发展。但如果没有数据的话,这些…

为了摸鱼,我开发了一个工具网站

🏡 博客首页:派 大 星 ⛳️ 欢迎关注 🐳 点赞 🎒 收藏 ✏️ 留言 🎢 本文由派大星原创编撰 🚧 系列专栏:《开源专栏》 🎈 本系列主要输出作者自创的开源项目 🔗 作品&…

“农场”技术栈是什么?浅聊FARM Stack

介绍 FARM 堆栈 - FastAPI、React 和 MongoDB。 长按关注《Python学研大本营》,加入读者群,分享更多精彩 扫码关注《Python学研大本营》,加入读者群,分享更多精彩 当我获得第一份编程工作时,LAMP(Linux、A…

[附源码]java毕业设计万科电子商城

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

【毕业设计】22-基于单片机的智能温度计的系统设计(原理图工程+仿真工程+源代码+仿真视频+答辩论文+答辩PPT)

【毕业设计】22-基于单片机的智能温度计的系统设计(原理图工程仿真工程源代码仿真视频答辩论文答辩PPT)[toc] 资料下载链接 资料下载链接 资料链接:https://www.cirmall.com/circuit/28616/ 包含此题目毕业设计全套资料: 基于单…

029-Swing实现简单计算器功能

https://blog.csdn.net/software7503/article/details/127952712https://blog.csdn.net/software7503/article/details/127952712上一讲:028-GUI事件处理,ActionListener事件,MouseListener事件 下一讲:030-用Swing组件及Action事件实现登录功能_CS

UNCTF2022 writeup

题量太多了,比赛结束之后又要做一遍… 注:最后给出的均为题目解出的flag,提交时需将格式修改为UNCTF{} 文章目录Web我太喜欢bilibili大学啦ezgame签到babyphpeasy_upload给你一刀我太喜欢bilibili大学啦修复版302与深大随便注PwnwelcomeUNCT…

企业日志分析ELK(Logstash+Elasticsearch+Kibana)介绍及搭建

一、ELK概述 1、ELK日志分析系统 ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。 ElasticSearch: ElasticSearch:是…

Linux:进程(一)

文章目录前言一、进程是什么二、描述进程--PCB三、查看进程四、通过系统调用获取进程标示符五、通过系统调用创建进程-fork初识六、进程状态七、进程状态查看八、僵尸进程(Z:zombie)1.是什么2.为什么3.怎么避免九、孤儿进程十、进程优先级十一…

内蒙古简易医院企业网设计与规划

目 录 摘 要 1 Abstract 2 第1章 绪论 5 1.1 背景及意义 5 1.2 国内外研究现状 6 1.2.1 国外研究现状 7 1.2.2 国内研究现状 7 1.3研究内容 8 第2章 医院企业网需求分析 9 2.1医院基本情况 9 2.1.1基本情况 9 2.1.2建筑楼群及信息点分布图 9 2.2需求需求 10 2.2.1管理需求 10 2…

Matlab下载安装详细教程

下载链接:https://pan.baidu.com/s/19JbPP2hWlZraVbLuNlHpcg 提取码:6666 下载网盘链接是公众号“电脑DIY圈”里的分享,不是博主自己的,另外此安装教程同样来自电脑DIY圈公众号,博主仅做整理,以便日后需要 …

图 知识点总结(王道)

图的定义 图G由顶点集V和边集E组成,记为G(V,E),其中V(G)表示图G中顶点的有限非空集;E(G)表示图G中顶点之间的关系(边)集合。若V{v1,v2vn},则用|V…

asp开发的人脸识别:人脸照片+身份证号+姓名,核验实人认证

今天接到一个客户需求,要求用asp开发人脸识别功能,主要用于网站上用户的实人核验,用户上传照片后,通过照片姓名身份证号码,核验是不是一个人,判断用户的真实性。asp写这个其实很简单,经过一个小…

黑*头条_第7章_kafka实战应用文章自动审核

黑*头条_第7章_kafka实战应用&文章自动审核 文章目录黑*头条_第7章_kafka实战应用&文章自动审核kafka实战应用&文章自动审核今日目标1 kafka封装1.1 功能需求1.2 定义1.2.1 约束定义1.3 实现设计1.4 开发实现1.4.1 配置文件1.4.2 KafkaMessage1.4.3 KafkaListener1…

SpringMVC ---- HttpMessageConverter

SpringMVC ---- HttpMessageConverter1. RequestBody2. RequestEntity3. ResponseBody4. SpringMVC处理json5. SpringMVC处理ajax6. RestController注解7. ResponseEntityHttpMessageConverter,报文信息转换器,将请求报文转换为 Java 对象,或…

[牛客top101]详解01,02,反转链表问题

文章目录前言1. 整体翻转链表1.1 题目描述1.2 题目详解2. 翻转链表的部分区间2.1 题目描述2.2 题目详解3. 完整代码展示前言 从本章开始,我们就开始刷题旅程啦,路上必定问题多多,但还是得练呐!所以,就现在,开始啦! 1. 整体翻转链表 1.1 题目描述 给定一个单链表的头结点pHea…

(续)SSM整合之springmvc笔记(拦截器)(P164-168)

目录 一 准备工作 1. 创建spring_mvc_extension com.atguigu 2 .导入依赖 3. 添加web模块 4 .web.xml 5 . springmvc.xml 6 index.html 7 控制层 8 success.html 9 .添加到tomcat ​10 测试 二 . 测试拦截器 1 . index.html 2 . FirstInterceptor …

Docker概念及安装

一、Docker概述 1 IT架构的演进: 裸金属 → 虚拟机 → 容器→ 函数化、代码化 云计算涌现出很多改变传统IT架构和运维方式的新技术,比如虚拟机、容器、微服务、Serverless(无服务),无论这些技术应用在哪些场景&…

智慧能源解决方案-最新全套文件

智慧能源解决方案-最新全套文件一、建设背景存在的问题二、建设架构三、建设方案四、获取 - 智慧能源全套最新解决方案合集一、建设背景 我国工业能耗占全国总能耗比例近70%,许多经济大省工业能耗占比甚至显著高于70%,工业企业能耗增速也明显领先全国其…