如何避免硬编码?在装饰器中

2023-11-21

我读过了“如何实现打字稿装饰器?”和多个来源,但有些事情我无法使用装饰器完成。

class FooBar {
    public foo(arg): void { 
        console.log(this);
        this.bar(arg);
    }
    private bar(arg) : void { 
        console.log(this, "bar", arg);
    }
}

如果我们调用该函数foo:

var foobar = new FooBar();
foobar.foo("test"); 

物体FooBar通过以下方式登录到控制台console.log(this); in foo

字符串"FooBar {foo: function, bar: function} bar test"通过以下方式登录到控制台console.log(this, "bar", arg); in bar.

现在让我们使用装饰器:

function log(target: Function, key: string, value: any) {
    return {
        value: (...args: any[]) => {
            var a = args.map(a => JSON.stringify(a)).join();
            var result = value.value.apply(this, args); // How to avoid hard coded this?
            var r = JSON.stringify(result);
            console.log(`Call: ${key}(${a}) => ${r}`);
            return result;
        }
    };
}

我们使用相同的函数但经过修饰:

class FooBar {
    @log
    public foo(arg): void { 
        console.log(this);
        this.bar(arg);
    }
    @log
    private bar(arg) : void { 
        console.log(this, "bar", arg);
    }
}

我们调用foo正如我们之前所做的:

var foobarFoo = new FooBar();
foobarFooBar.foo("test");

物体Window通过以下方式登录到控制台console.log(this); in foo

And bar永远不会被调用foo因为this.bar(arg); causes Uncaught TypeError: this.bar is not a function.

问题是硬编码this在 - 的里面log装饰器:

value.value.apply(this, args);

怎样才能保存原来的this value?


不要使用箭头函数。使用函数表达式:

function log(target: Object, key: string, value: any) {
    return {
        value: function(...args: any[]) {
            var a = args.map(a => JSON.stringify(a)).join();
            var result = value.value.apply(this, args);
            var r = JSON.stringify(result);
            console.log(`Call: ${key}(${a}) => ${r}`);
            return result;
        }
    };
}

这样它将使用该函数的this上下文而不是值this当调用日志时。


顺便说一句,我建议编辑描述符/值参数并返回它,而不是通过返回新描述符来覆盖它。这样,您可以将当前属性保留在描述符中,并且不会覆盖另一个装饰器可能对描述符所做的操作:

function log(target: Object, key: string, descriptor: TypedPropertyDescriptor<any>) {
    var originalMethod = descriptor.value;

    descriptor.value = function(...args: any[]) {
        var a = args.map(a => JSON.stringify(a)).join();
        var result = originalMethod.apply(this, args);
        var r = JSON.stringify(result);
        console.log(`Call: ${key}(${a}) => ${r}`);
        return result;
    };

    return descriptor;
}

这个答案中有更多详细信息- 请参阅“示例 - 无参数 > 注释”下的“坏与好”示例

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何避免硬编码?在装饰器中 的相关文章

  • javascript 中对象的“异步”循环

    通常 我们可以对数组和对象进行循环来迭代属性 值 但循环是阻塞的 但是 超时可用于模拟异步循环 我设法为数组做到了这一点 http jsfiddle net LHhy2 do stuff function asyncLoop i do st
  • 无法在 JavaScript for 循环中读取 null 的属性“长度”

    我正在尝试制作一个像 Stack Overflow 那样的 Markdown 编辑器 如果我实际上没有在文本区域中键入星号和包含短语的 http 我会收到标题中列出的此错误 如果我只输入包含星号的短语 则错误指的是这一行 if linkif
  • 使用 javascript 更改 div 颜色

    div style height 20px width 100 background color 000000 div br
  • 定义 js-xlsx 单元格范围

    我正在尝试使用 js xlsx 读取 Excel 值 我可以使用以下代码从工作簿工作表中获取单元格值 if typeof require undefined XLSX require xlsx var workbook XLSX readF
  • Angular 2 Material 2 日期选择器日期格式

    我不知道如何更改材料2日期选择器的日期格式 我已阅读文档 但我不明白我实际上需要做什么 datepicker默认提供的输出日期格式为f e 6 9 2017 我想要实现的目标是将格式更改为类似的格式9 Jun 2017或任何其他 文档htt
  • 仅单击 div 内部

    我正在为一个小网站制作教程 我只想让教程气泡可点击 因此 当我们尝试单击气泡之外的某些内容时 什么也不会发生 换句话说 我希望我的 html 不可点击 而 tutorial bubble 可点击 尝试这个 jQuery function h
  • Javascript - 在加载所有图像后执行

    看了别人的问题我想 window onload 会回答我的问题 我已经尝试过这个 但它会在页面加载时立即执行代码 而不是在图像加载之后 如果有什么区别的话 图像来自 CDN 并且不是相对的 有人知道解决办法吗 我没有使用 jQuery 想要
  • 限制可选 DOM 复选框

    我试图限制用户可以选择的复选框数量 这些复选框是为数组中的每个项目生成的 DOM 输入对象 我目前对此没有运气 因此非常感谢任何帮助 谢谢 在这里小提琴 http jsfiddle net vVxM2 222 http jsfiddle n
  • 以一定时间间隔连续重复运行 JavaScript 函数

    这是我的第一个问题 希望您尽快回答 我想要代码连续重复一个函数 我尝试了一些代码 但没有成功 我尝试了这段代码 我想在一段时间后重复这个功能 我努力了setInterval and setTimeout 但是 我还没有收到结果 这将重复该任
  • 如何动态突出显示网页上的字符串?

    我想创建带有 url 的页面 例如 http xyzcorp schedules 2015Aug24 Aug28 Jim Hawkins http xyzcorp schedules 2015Aug24 Aug28 Billy Bones
  • 将文本大小调整为矩形 在 Canvas HTML5 中调整大小

    我是 Canvas 新手 我正在创建一个网站 以在调整矩形大小时增加文本 我尝试了很多 但没有任何效果 实际上 我希望如果我仅按其宽度调整矩形大小 向左拉伸 向右拉伸 则仅应增加文本宽度而不是字体大小 我已经完成了字体大小 但发现增加孤立文
  • 如何使用 Angular JS 单击时将 html 模板附加到 div/指令?

    我有这种情况
  • 循环遍历元素并逐步为每个元素应用 CSS 规则

    我有一个网格布局 每个网格布局中都有不同数量的元素 我想动态添加内联grid column通过循环遍历 div 中存在的每个元素的 CSS 规则 ul 与一类 list 所以 HTML 代码的输出需要是 ul class list ul u
  • console.log() 显示同一对象属性的矛盾值

    我想我可能要疯了 我使用 console log 来查看对象的状态 然后在下一行对同一对象的特定属性执行 console log 并为每个属性获取不同的值 我正在使用的代码是 console log this pictures Items
  • 在 React Navigation 中将 props 传递给自定义抽屉导航器

    在反应导航抽屉菜单中 我想显示用户名 John Doe 它处于我的主要组件的状态 Router 我怎样才能将自定义抽屉内容组件传递给它 额外信息 我从 AsyncStorage 中获取此名称 组件已挂载 这是我的代码 export defa
  • 如何在 ASP.NET MVC 3 的 Razor 视图中编码嵌入的 javascript?

    如何在以下上下文中正确编码 JavaScript 我的 JSON 对象中的值是由应用程序管理员设置的 因此我假设它们需要正确编码 对于 HTML 和 JavaScript 都是如此 我在用着System Web Script Seriali
  • 如何处理requireJs超时错误?

    我正在使用 require js 作为加载框架编写一个移动混合应用程序 我遇到加载错误的问题 我想做的是在设备离线且无法下载在屏幕上显示地图所需的 google 地图 API 脚本时设置后备解决方案 我得到的只是 Uncaught Erro
  • 使用 AngularJS 多部分表单数据将文件上传到 Google Cloud Storage

    我正在尝试使用 AngularJS 中指定的多部分方法将图像文件上传到 Google Cloud Storagehttps cloud google com storage docs json api v1 how tos upload m
  • MongoDB中如何通过引用字段进行查询?

    我有两个 Mongo 模式 User id ObjectId name String country ObjectId Reference to schema Country Country id ObjectId name String
  • 强制输入数字小数位

    我想强制

随机推荐

  • ng-disabled 无法使用引导按钮

    我正在使用 bootstrap js 和 Angular js 我的代码如下 few lines from controller scope isWaiting true scope promise http get voluumHandl
  • Rails:模型中未定义的方法“截断”

    我的模型中有以下方法可以裁剪记录的描述 但由于未知原因 截断方法不起作用 def cropped description nb words max 500 if description length gt nb words max trun
  • 如何检测驱动器中是否有软盘?

    我尝试使用 DriveInfo IsReady 但如果驱动器中有未格式化的软盘 它会返回 false 您始终可以尝试从软盘读取扇区 看看是否成功 我不知道如何在 NET 中执行此操作 但这里是 C C 等效项 SetLastError 0
  • 来自 x509 证书的 golang 主题 dn

    有没有简单的方法可以从 go 中的 x509 证书中以字符串形式获取完整的主题 DN 或颁发者 DN 我无法在 pkix Name 中找到任何类似 String 的方法 解决方案 感谢同事 var oid map string string
  • 有没有比这更快的方法来计算Python中文件的哈希值(使用hashlib)?

    我目前的做法是这样的 def get hash path PATH hash type md5 func getattr hashlib hash type with open path rb as f for block in iter
  • Laravel 文件不存在 - 文件上传

    我正在使用表单上传视频文件 由于某种原因 我得到的只是以下错误 Symfony Component HttpFoundation File Exception FileNotFoundException The file does not
  • 我是否可以强制将模型属性的更新注册为更改(即使不是)?

    我知道我可以设置 Backbone 模型属性的值 这样它就不会触发change事件使用 沉默 真实 我还知道 如果我将模型的属性设置为它已有的值 它不会触发更改事件 这几乎总是一件好事 但是 有没有办法强制模型更新触发更改事件 即使它设置为
  • 按值重载运算符会导致使用移动的值

    编译以下使用运算符重载的 Rust 代码 use std ops Add derive Show struct Point x int y int impl Add for Point type Output Point fn add se
  • Visual Studio代码:自动提交git

    很多时候 我忘记将我的编辑提交到我的 git 中 如果我关闭了 VSCode 我就不能再使用 ctrl Z 了 因为 我已经设置了 git 我想我可以使用类似每 30 秒左右自动提交一次的东西 我见过这个扩大btu ti 不是开源的 所以我
  • 如何将主题应用到 元素

    我有一个扩展 PreferenceActivity 的活动 我的主题 android theme android style Theme Light NoTitleBar Fullscreen 应用于清单文件中的应用程序级别 除了 Pref
  • 为 PhoneGap 应用程序嵌入 PDF 查看器

    如何为phonegap 应用程序嵌入PDF 查看器 我决定使用 PhoneGap Sencha Touch 开发适用于 iOS 和 Android 的应用程序 我只有 iOS PhoneGap 经验 对我有用的解决方案是制作一个插件 弹出一
  • 如何在 C# 中将字符串解码为 XML 字符串

    我有一个包含 XML 描述的字符串 来自 CDATA 元素 我需要使用 C 将此字符串解码为一个可以正确显示字符的新字符串 现有字符串 lt xml version 1 0 encoding UTF 8 standalone yes gt
  • XNA 3d 物理引擎 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我正在寻找 XNA 的 3
  • Android jacoco 覆盖率空与 gradle

    我正在尝试让 jacoco 为我的 android 测试项目创建一个代码覆盖率报告 我在 build gradle 中有以下内容 apply plugin com android application apply plugin jacoc
  • 使用 osascript -e“显示通知”时更改通知图标

    我正在尝试为 emacs 编写一个插件 使用 OS X 的本机通知显示来显示通知 我遇到过terminal notifier这是可行的 但它是一个依赖项 并不适用于每台 Mac 另外 应该让用户知道他们需要安装该软件包 我想做的是调用一个进
  • 在 IE8 标准模式下对 IE8 中呈现的本地 html 文件使用 BASE 元素时缺少样式表/脚本/图像

    我们有一些 HTML 页面 本地的 而不是 Web 服务器上的 它们使用 BASE 元素来标识包含一堆常见样式表和图像的特定基本目录 这是一个示例 页面存储在 c temp html test html 中 资源目录是 c temp res
  • std::unique_ptr reset() 操作顺序

    Calling void reset pointer ptr pointer noexcept 调用以下操作 给定 current ptr 由 this 管理的指针 按以下顺序执行以下操作 保存当前指针的副本 old ptr current
  • 如何从命令行使用 BigQuery REST API?

    尝试向 BigQuery REST API 之一发出普通 GET 请求会出现如下错误 curl https www googleapis com bigquery v2 projects PROJECT ID jobs JOBID Outp
  • 关于异步套接字操作和消息帧的.NET问题

    我一直在到处寻找有关如何处理 TCP 消息帧的示例 我看到许多示例 其中 NetworkStreams 被传递到 StreamReader 或 StreamWriter 对象中 然后对 n 分隔消息使用 ReadLine 或 WriteLi
  • 如何避免硬编码?在装饰器中

    我读过了 如何实现打字稿装饰器 和多个来源 但有些事情我无法使用装饰器完成 class FooBar public foo arg void console log this this bar arg private bar arg voi