有没有办法使用 Javascript ES6 代理来监视对象方法[重复]

2023-12-23

考虑到以下对象是否可能

let target = {
 foo:0,
 result:[],
 bar(){
   //some code
 }
}

然后将所述对象包装在Proxy()

let handler = {
  get(){
    // code here
  },
  apply(){
    // code here
   }
 }

 target = new Proxy(target,handler);

接听电话bar()并将结果保存到results:[] ?

我已经尝试过几次了

let target = {
    called:0,
    results:[],
    foo(bar){
        return bar;
    },
}

let handler = {
    get(target,prop){
        console.log('Get Ran')
        return target[prop];
    },
    apply(target,thisArg,args){
        console.log('Apply Ran')
        // never runs
    }
}

target = new Proxy(target,handler);
target.foo();

此代码错过了 [[ apply ]] 但捕获了 [[ get ]] (如果没记错的话,对象方法调用作为两个操作完成,[[ get ]] [[ apply ]])

let target = {
    called:0,
    results:[],
    foo(bar){
        return bar;
    },
}

let handler = {
    get(target,prop){
        return target[prop];
    },
    apply(target,thisArg,args){
        let product = target.apply(thisArg,args)
        return product;
    },
}

let prox = new Proxy(target.foo,handler);
    console.log(prox('hello'));

如果我将对象方法包装在代理中,它会捕获 [[ apply ]] 但我失去了对原始对象( this )的引用,因此失去了对结果数组的访问

我还尝试将方法代理嵌套在对象代理内。

有什么想法吗 ?

我的实际代码的 CodeSandBox https://codesandbox.io/s/frosty-kowalevski-8y4co?file=/src/index.js

// 代理的文档

代理MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Javascript.info/代理 https://javascript.info/proxy

// 关于代理的其他问题,但不是这个用例

了解 ES6 javascript 代理 https://stackoverflow.com/questions/48527262/understanding-es6-javascript-proxies


根据spec https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist

如果代理异常对象的 [[ProxyTarget]] 内部槽的初始值是具有 [[Call]] 内部方法的对象,则该对象仅具有 [[Call]] 内部方法。

因此,如果目标是 a,下面确实会捕获调用function

(new Proxy(() => 'hello', { apply: () => console.log('catched') }))() // 'catched

相反,如果目标没有调用方法,则没有代理

try {
  (new Proxy({}, { apply: () => console.log('catched') }))() // throws
} catch (e){ console.log('e', e.message)}

所以提示可能是代理 [get] then 而不是返回值(作为函数bar,代理该值以捕获最终调用

const p = new Proxy(
  { results: [], bar: () => { console.log('rywhite') } }, {
  get: (target, prop) => {
    if (prop !== 'bar') return target[prop]
    return new Proxy (target.bar, {
      apply () {
        target.results.push('what')
      }
    })
  }
})
p.bar // nothing bud'
p.bar(); console.log('res', p.results)
p.bar(); console.log('res', p.results)
p.bar(); console.log('res', p.results)

编辑:注意:没有必要每次都创建一个新的代理

在下面的代码中,返回相同的代理大约快两倍

const N = 1e6
{
  const target = { results: 0, bar: () => { console.log('rywhite') } }
  const p = new Proxy(
    target, {
    get: (() => {
      const barProxy = new Proxy (target.bar, {
        apply () {
          target.results++
        }
      })
      return (target, prop) => {
        if (prop !== 'bar') return target[prop]
        return barProxy
      }
    })()
  })
  console.time('go')
  for (let i = 0; i < N; ++i) { p.bar() }
  console.timeEnd('go')
  console.log('res', p.results)
}
{
  const p = new Proxy(
    { results: 0, bar: () => { console.log('rywhite') } }, {
      get: (target, prop) => {
        if (prop !== 'bar') return target[prop]
        return new Proxy (target.bar, {
          apply () {
            target.results++
          }
        })
      }
    })
  console.time('neweverytime')
  for (let i = 0; i < N; ++i) { p.bar() }
  console.timeEnd('neweverytime')
  console.log('res', p.results)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有办法使用 Javascript ES6 代理来监视对象方法[重复] 的相关文章

  • 如何清除ember js中的表单数据

    嗨 我对 ember js 很陌生 我写了一个新员工入职表格 并通过路线发送数据 数据保存成功 但问题是提交表单后我的表单数据没有清除 代码如下 app js App Router map function this resource sa
  • D3.js分组条形图

    I am making a bar chart using D3 js like this source statcan gc ca http www statcan gc ca pub 12 593 x 2007001 figures f
  • 为什么可以从 console.log 访问 JavaScript 私有方法

    我写了一个简单的代码 const secure new class privateProperty 4 privateMethod console log The property this privateProperty should n
  • Angular JS - 提交到 $http 时日期发生变化 - 时区问题

    我遇到一个奇怪的问题Date当它通过 http put 传递到 API 时发生变化 我怀疑时区问题 Datepicker 触发 ng change 事件 console log Tue Jun 10 2014 00 00 00 GMT 01
  • 使用 Intern 测试自定义 JavaScript(不是 Node 模块)

    是否可以为自定义客户端创建和运行测试套件 JavaScript 不是作为 Node 模块创建的 应该如何 那么配置要改吗 Intern 配置中有 loader 部分 指定了 如果我做对了 将会加载的包 是否有必要 以某种方式在这里包含我的自
  • 检查复选框是否被选中? [复制]

    这个问题在这里已经有答案了 如何通过 jQuery 检查复选框是否被选中 我可以只向元素添加 ID 或类并执行此操作吗 if element val 1 do stuff if element is checked checkbox is
  • contenteditable,在文本末尾设置插入符号(跨浏览器)

    输出在Chrome div style border 1px solid 000 width 500px height 40px hey div what s up div div div div
  • jQuery 模式窗口从我的表单中删除元素

    jQuery 当我用它创建一个包含表单元素的模式窗口时 当我提交表单时 它会取出这些元素 表格示例
  • Android 上的 Chrome 强制隐藏地址栏

    我最近开发了一个获取混合 http https 内容的网站 因此 我总是将地址栏显示在顶部 它不会像其他网站那样自动隐藏 这就是我要说的 This https planetkde org 是网站的链接 内容是从各种来源获取的 因此无法过滤非
  • WaveSurfer JS 无法在 Firefox 中为特定的 mp3 音频文件生成图表

    我们面临着在 Firefox 中使用 wavesurfer JS 对某些特定格式的 mp3 文件绘制音频可视化 图表 的问题 它总是给我们这样的错误 传递给decodeAudioData 的缓冲区包含未知的内容类型 但同一个文件在 chro
  • 在 JavaScript 中引用 C# 变量

    我已经阅读了很多线程 但我不明白为什么这不起作用 我正在创建一个将用作导航栏的 SharePoint Web 部件 一切都很顺利 直到我尝试在 JS 代码中引用 C 变量 这是来自 VisualWebPart1UserControl asc
  • ajax 调用成功后点击链接 href

    我有一个正常的链接 a href http www google com class continue Continue a 我已将点击绑定到一个事件来发布 ajax 请求 如下所示 continue click function ajax
  • 检测 iPad Safari 用户的最佳方法

    添加用于检测 iPad Safari 用户的代码的最佳方法是什么 我的意思是我们应该使用 1 CSS 通过链接媒体 2 JS 通过navigator对象 我听说使用用户代理字符串并不是检测 iPad 的最佳方法 因为存在不一致的情况 请建议
  • 将 DIV 转换为单击并拖动视口

    有人知道一种不显眼的 基于原型或无框架的方法将具有大内容 例如地图 的 DIV 转换为具有固定尺寸的可点击和可拖动的 地图 容器 非常像 Google 地图 我想在大型输入表单中显示 HTML 块 这些块可能会超出可用空间 每个块可以有大约
  • 如何在javascript中删除一组表情符号中的最后一个表情符号?

    假设我的字符串中有 3 个表情符号 字符串中没有任何空格或除表情符号之外的任何其他字符 如何删除javascript中最后一个表情符号 下面的答案不使用任何特殊的包并安全地删除最后一个表情符号 function safeEmojiBacks
  • 启动 onclick 比使用 document.onload 更快

    我有带有链接的 html 页面 我想在其中附加一个功能onclick事件 一种方法当然是 a href save php Save a 但我知道这不是最佳做法 所以我反而等待window onload 循环遍历链接并将保存功能附加到链接re
  • 什么是闭包编译器?

    如果您不知道我在说什么 请查看以下内容 http closure compiler appspot com home http closure compiler appspot com home 这是一个 JavaScript 压缩器 在他
  • JavaScript:嵌套循环?

    我想实现这样的动画 序列 动画以循环开始 想象一下car从 x1 移动到 x2 然后暂停 1 秒 然后再次播放动画 想象一下car从 x2 移动到 x3 等 the car循环是通过向汽车左侧添加 1px 来实现的 值 但我无法弄清楚嵌套循
  • 将罗马数字转换为阿拉伯数字--recursiv

    我是 JavaScript 新手 正在网站的帮助下学习https www jshero net koans roman1 html https www jshero net koans roman1 html 本练习是编写一个转换器 将罗马
  • TinyMCE:将 CSS 类属性与 formatselect-dropdown 格式结合使用

    我想定制格式 http wiki moxiecode com index php TinyMCE Configuration theme advanced blockformats在 TinyMCE 中格式选择下拉菜单 http wiki

随机推荐

  • 法拉第超时

    我已经在线搜索了文档和其他地方 似乎无法想出为法拉第设置超时选项的正确方法 有人有答案吗 我试过了 conn FaradayStack build url conn headers user agent AppConfig user age
  • 使用Phantom.js评估,如何获取页面的HTML?

    page evaluate function return document function result console log result next 结果实际上是一个巨大的物体 我不知道该对象的属性和属性 我只想要页面的 HTMLa
  • R 中 3 个分类变量和 1 个连续变量的 SE 点图

    我正在尝试生成一个点图 其中包含具有三个分类变量 mea tre 和 sex 的设计中单个测量值 len 的值 I ve produced a plot that has all I m looking for split across s
  • Google 地图 v3:大尺寸标记

    我需要在地图上显示标记 它运行良好 唯一的问题是它们看起来太小了 如何确保所使用的标记尺寸较大并且几乎在任何缩放状态下都可以看到 为了使图标更大 我绝对建议使图标图像更大 例如 要使用缩小的高分辨率图标修复高 dpi 移动设备上的像素图标
  • 打开 Storyboard 时 Xcode 8 挂起/无响应

    我最近升级到了 Xcode 8 并将我的项目更新到了 Swift 3 一段时间内一切都运行良好 故事板加载一直很慢 即使仍然运行 Xcode 7 并且与 Xcode 8 几乎一样 慢 我一直以为这是因为我使用的是较旧的 2011 年末 Ma
  • git-log 和 git-whatchanged 之间的区别?

    Given 这个答案 https stackoverflow com a 280140 10608另一个问题 以及 鉴于两者的手册页git log http linux die net man 1 git log and git whatc
  • 字符串文字作为方法的参数

    Java 中的任何字符串文字都是类型的常量对象String并存储在字符串文字池中 Will String作为参数传递给方法的文字也存储在String文字池 例如当我们写的时候 System out println Hello OR anyo
  • Bootstrap3 Affix 中的 data-offset-bottom

    我想从我的附加元素中设置 停止 例如投票http 9gag com http 9gag com 它滚动直到其父容器 我为此使用了affix 我发现了 data offset bottom 属性 没有太多记录 div class homepa
  • IE JQuery 就绪功能不起作用

    显然很多人都遇到过这个问题 但我还没有找到有效的解决方案 我有一些代码需要在页面加载后运行 因此我将其粘贴在以下块中 document ready function alert Running initialization initiali
  • 使用端口 80 时 Apache 服务失败(“繁忙”)[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何配置 Apache 服务器在端口 80 上运行 我的 Apache 服务在使用端口 80 时失败 它说BUSY 当我将配置中的端口更改
  • 通过 JSch shell 执行多个命令

    我试图使用 JSch 库通过 SSH 协议执行多个命令 但我似乎陷入困境 找不到任何解决方案 这setCommand 方法每个会话只能执行单个命令 但我想像Android平台上的connectbot应用程序一样顺序执行命令 到目前为止我的代
  • 批量上传大图片到cloudinary

    有没有办法将图像批量上传到我的 cloudinary 帐户 我希望一次导入 100 张图像 每张图像 3MB 谢谢 您可以使用Cloudinary的上传API来一张一张上传图片 这是 Python 中的示例上传代码 https github
  • Xcode 8 beta 6:main.swift 无法编译

    我们有一个自定义的 UIApplication 对象 所以我们的 main swift 是 import Foundation import UIKit UIApplicationMain Process argc Process unsa
  • 通过 Azure DevOps 中的 EFCore 迁移更新 postgreSQL DB

    在Azure DevOps中 我用来更新的方式SQL服务器数据库使用 Entity Framework Core 使用两个任务 在我的构建管道中 这个任务 https github com pekspro EF Migrations Scr
  • HTML5中拖动时如何更改光标图标?

    当用户拖动 DIV 以下示例中的红色 div 时 我需要设置光标图标 我尝试过几次尝试 包括使用 CSScursor move and event dataTransfer dropEffect没有成功 因为图标总是显示 交叉圆圈 有什么想
  • ES6中使用嵌套类模拟命名空间

    我有一个文件 Services js我正在尝试将所有个人服务加载到其中 这些服务作为单例公开 Services js var Services export default Services 然后我希望示例服务嵌套在服务下 这样我就可以调用
  • 修改部分XML元素名称并替换为增量编号

    是否可以使用 XSLT 将部分元素名称更改为带有增量编号的另一个元素名称 就像我只想更改以 UPC 开头的元素名称
  • 如何将图像添加到画布

    我正在尝试使用 HTML 中的新 canvas 元素 我只是想将图像添加到画布上 但由于某种原因它不起作用 我有以下代码 HTML
  • 将 Activity 的引用传递给实用程序类 android

    我知道这个问题已经被问过很多次了 但我仍然无法完全理解这个概念 在我的应用程序中 我使用静态实用程序类来保留常用方法 例如显示错误对话框 这是我的静态类的样子 public class GlobalMethods To show error
  • 有没有办法使用 Javascript ES6 代理来监视对象方法[重复]

    这个问题在这里已经有答案了 考虑到以下对象是否可能 let target foo 0 result bar some code 然后将所述对象包装在Proxy let handler get code here apply code her