Javascript 代理和扩展语法,与 console.log 相结合

2023-12-20

因此,我在尝试使用 Proxy 对象并尝试了解它们如何与扩展语法和解构混合时,我偶然发现了这种奇怪的行为:

const obj = {
  origAttr: 'hi'
}

const handler = {
  get(target, prop) {
    console.log(prop);
    return 1;
  },
  has(target, prop) {
    return true;
  },
  ownKeys(target) {
    return [...Reflect.ownKeys(target), 'a', 'b'];
  },
  getOwnPropertyDescriptor(target, key) {
    return {
      enumerable: true,
      configurable: true
    };
  }
}

const test = new Proxy(obj, handler);
const testSpread = { ...test};

console.log('Iterate test');
// Works OK, output as expected
for (const i in test) {
  console.log(i, ' -> ', test[i]);
}

console.log('Iterate testSpread');
// Also works OK, output as expected
for (const i in testSpread) {
  console.log(i, ' -> ', testSpread[i]);
}

console.log('Here comes the unexpected output from console.log:');
console.log(test); // All attributes are 'undefined'
console.log(testSpread); // This is OK for some wierd reason

上述脚本输出(在节点 v10.15.1 上):

这是控制台日志的意外输出:

Symbol(nodejs.util.inspect.custom)
Symbol(Symbol.toStringTag)
Symbol(Symbol.iterator)
{ origAttr: undefined, a: undefined, b: undefined }
{ origAttr: 1, a: 1, b: 1 }

为什么console.log(test);输出显示对象的属性全部未定义?如果在调试某些东西时发生这种情况,可能会导致一些严重的头痛。

这是节点本身的错误还是console.log的实现中的错误?


好吧,我做了一些更多的挖掘,并将整个过程追溯到在我的代理对象上调用 Object.getOwnPropertyDescriptor 以获取其属性的值。

但在我的例子中,“value”属性显然是未定义的,因为我有一个 getOwnPropertyDescriptor 陷阱,它只指定可枚举和可配置的属性(从而可以迭代数组,将其与扩展运算符一起使用等)。 由于没有从 getOwnPropertyDescriptor 陷阱调用 get 陷阱的标准方法,因此恕我直言,这实际上无法修复。不过,如果被证明是错误的,那就很有趣了:)

嗯,正如 Bergi 在评论中指出的那样,有一个标准的方法。

也在文档中https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Parameters https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor#Parameters“这与处理程序绑定”

编辑我的代码以反映这一点。

演示 getOwnPropertyDescriptor 行为的代码如下:

const obj = {
  origAttr: 'hi'
}

const handler = {
  get(target, prop) {
    return 1;
  },
  has(target, prop) {
    return true;
  },
  ownKeys(target) {
    return [...Reflect.ownKeys(target), 'a', 'b'];
  },
  getOwnPropertyDescriptor(target, key) {
    return {
      value: this.get(target, key),
      enumerable: true,
      configurable: true
    };
  }
}

const test = new Proxy(obj, handler);
const testSpread = { ...test
};

// Defined, due to trapped getOwnPropertyDescriptor which returns a value attribute
console.log(Object.getOwnPropertyDescriptor(test, 'origAttr'))

// Defined, because it is a regular object, not a proxy with a getOwnPropertyDescriptor trap
console.log(Object.getOwnPropertyDescriptor(testSpread, 'origAttr'))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript 代理和扩展语法,与 console.log 相结合 的相关文章

随机推荐

  • 以静态大小的数组作为参数的通用 lambda

    以下通用 多态 lambda 是否合法 C 14 auto f auto x 3 x 0 x 1 etc GCC 和 Clang 4 接受该代码 但 Visual Studio 2017 不接受 合法吗 error C3318 auto 3
  • 反应本机文本颜色不起作用

    我有一个Text里面的组件TouchableOpacity我想改变颜色取决于变量 这是我的代码 import React Component from react import StyleSheet Text View TouchableO
  • CUDA 小内核 2d 卷积 - 如何做

    我已经用 CUDA 内核试验了几天 在 500x500 图像 但我也可以改变尺寸 和非常小的 2D 内核 拉普拉斯 2d 内核 所以它是 3x3 内核 太小 之间执行快速 2D 卷积以利用所有 cuda 线程的巨大优势 我创建了一个 CPU
  • 使用 val() 设置输入值时会触发什么 jquery 事件?

    我可以设置这个监听器 input type text on keyup paste input change function console log Hello 如果我打开DevTools and do input type text v
  • 使用 PHP 将 Javascript 时间转换为 MySQL 格式

    我怎样才能转换js日期 像这样Sun Jul 13 2014 07 00 00 GMT 0200 EET 到 MySQL 格式 像这样2014 07 13 07 00 00 使用PHP 由于您的日期字符串已经包含时区 因此您不需要执行任何特
  • 在eclipse中调试黑莓应用程序“找不到源”问题

    我正在 Eclipse 中调试一个应用程序 它工作正常 但在某些方法上 例如输入EventDispatcher 它显示我找不到源 应附加哪些源文件以避免此问题 我不太清楚 听起来您正在尝试调试 RIM BB 操作系统代码 据我所知 RIM
  • 我可以让 Swing JButton 的边距更小吗?

    我更喜欢边距最小的按钮 大约与文本标题一样宽 有没有办法在 Swing 的 JButton 中实现这一点 我现在在实践中看到的是 即使我尝试使用 setMaximumSize 和类似的方法 它最终也会吃掉文本标题 将其从右侧切断 但这并没有
  • 查询中的日期格式更改

    我在 android 中使用 PHP JSON 作为 API 我使用下面的代码从 MYSQL 数据中获取新闻 它工作正常 但日期格式显示为年 月 日 但我想要得到它日 月 年 我搜索了很多但没有找到任何解决方案 这里有人可以解决我的问题吗
  • 如何在 Ant 中动态包含 ant-contrib.jar

    我正在寻找一种方法来包含 Ant 文件中的 jar 以便我可以立即使用它并在我的目标中调用它的方法 就我而言是ant contrib 1 0b3 jar 最好的方法是将 Ant Contrib jar 文件放入您的项目中 例如 假设buil
  • Python ftplib.error_perm: 530 登录验证失败

    我想编写一个脚本来连接我的 FTP 服务器 但它对我不起作用 from ftplib import FTP ftp FTP ftp set debuglevel 2 ftp connect 192 169 137 100 ftp login
  • 有没有办法使用 Perl 脚本更改 Windows 文件夹图标?

    有没有办法使用 Perl 脚本更改 Windows 文件夹图标 我的目的是将 xxx documents 文件夹的普通图标更改为其他图标 我必须以照顾整个驱动器的方式运行脚本 该驱动器包含许多文件夹 我必须搜索每个名为 文档 的文件夹 例如
  • protobuf-net:无法序列化类型数据,如何使用协议缓冲区定义类型数据?

    我正在尝试创建一个简单的内存网格 可以使用协议缓冲区进行序列化 这个想法是用户可以创建 定义任何类型的列 基元或用户定义的列 只要它们是协议缓冲区标记的 我的问题是你无法使用协议缓冲区序列化类型数据 那么我该如何实现这一点 下面的代码显示了
  • 如何防止按 Enter 键结束 DataGridView 中的 EditMode?

    我在 Windows 窗体应用程序中有一个自定义 DataGridView 控件 当用户按下 Enter 键时 我不希望发生任何事情 我已经重写了自定义 DataGridView 中的 OnKeyPress 方法 以防止 SelectedC
  • Firemonkey 应用程序中的最小化表单

    我用这个 Application Minimize 在 Vcl delphi 应用程序中 但在 Firemonkey 中我有未声明的标识符 error 如何最小化我的火猴形态 尝试使用WindowState http docwiki emb
  • 如何在 Java for Android (Eclipse) 中插入 swf 动画(flash)

    我已经在谷歌上搜索了好几天了 但仍然找不到任何东西 我已经尝试过一些代码 但我对java也很菜鸟 所以我尝试过的每一个代码都失败了 好吧 我将尝试解释一下 我正在编写一个使用 3 个活动的应用程序 第一个活动有一个打开第二个活动的按钮 在第
  • 使用正则表达式匹配 url 中的文件夹名称

    我只想匹配文件所在的文件夹名称 eg pic 2009 cat01 jpg图片 2009 01 cat02 jpg 我想只匹配我用粗体输入的内容 到目前为止我有这个 哪个会匹配 图片 2009 猫01 jpg 任何想法 不确定我明白你在问什
  • 编辑文件时保留 samba 共享的文件权限

    我使用的代码库是从 Git 存储库检出到我的 Linux 机器上的 由于我们的生产代码是为了部署在 Linux 上而编写的 因此我在 Linux 计算机上进行了所有测试 但喜欢使用 Windows 进行日常使用 包括代码编辑 创作 为此 我
  • 在 Windows 中调整位图大小的最佳方法是什么?

    所以 我正在开发一个文本编辑器 我使用双缓冲在屏幕上绘画 所以基本上我有一个屏幕外位图 我在上面绘制 然后将其复制到屏幕上 现在 当文本编辑器窗口调整大小时 我还需要调整屏幕外位图的大小 那么调整位图大小的好方法是什么 我想也许删除旧对象并
  • eclipse xml编辑器使用空格缩进

    我的eclipse版本是Mars Release 4 5 0 Preferences gt XML gt XML Files gt Editor 我无法设置缩进大小的值 和 无法点击 我还无法输入值 遇到同样的问题 我找到了以下解决方法 使
  • Javascript 代理和扩展语法,与 console.log 相结合

    因此 我在尝试使用 Proxy 对象并尝试了解它们如何与扩展语法和解构混合时 我偶然发现了这种奇怪的行为 const obj origAttr hi const handler get target prop console log pro