【问题标题】:How to properly assign property to function scope?如何正确地将属性分配给功能范围?
【发布时间】:2022-01-15 06:34:31
【问题描述】:

我最近一直在试验 Typescript 装饰器,以尝试解决我在应用程序中遇到的“问题”。我正在使用 JS 桥将 TS 代码提供给 Android 和 iOS,目前我们声明这样的函数:

index.js

import foo from './bar'

global.App = function() {
  this.foo = foo;
};

以上内容将使foo 函数在桥的本机端可用

我想编写一个装饰器来应用 foo 方法,该方法将在 global.App 上“注册”自身,但我在该任务中失败了。

这是可以工作的装饰器:

export const Task = (target, propertyKey, descriptor) => {
    let originalMethod = descriptor.value;
    descriptor.value = (...args) => originalMethod.apply(target, args);

    if (!global.App) {
        global.App = function () { 
            this.foo = descriptor.value;
        };
    }
    
    return descriptor;
}

如何向 global.App 函数添加另一种方法?

【问题讨论】:

  • 您的代码将global.App 设置为function,但您只需尝试将其值设置为简单值。目前尚不清楚您要达到的目标。
  • 每当我们为 global.App 函数设置一个属性时,该属性就可以通过桥在本机端访问,因此我们可以调用我们为该属性设置的方法
  • 您的网桥中可能有一个自定义行为调用 global.App。正如 Pointy 的评论所指出的,在一种情况下,您将其设置为一个函数,而在另一种情况下,您将其设置为一个已经存在的对象。另请注意,您可能被this误导。
  • 在这种情况下,这是指我分配给global.App 的内部函数,对吗?如何向global.App 添加另一个属性?

标签: javascript typescript typescript-decorator


【解决方案1】:

首先,foo 方法只添加一次,因为第一次调用装饰器 global.App 已定义,并且将 foo 添加到 global.App 的分支永远不会重新进入。

其次,global.App 和 foo 每次都会被覆盖,并且不会通过重复调用装饰器来维护。

添加另一个分支来处理在第一次调用后添加方法并动态分配方法的名称,我相信这是在propertyKey 中提供给装饰器的,将允许添加多个方法。

export const Task = (target, propertyKey, descriptor) => {
    let originalMethod = descriptor.value;
    descriptor.value = (...args) => originalMethod.apply(target, args);

    if (!global.App) {
        global.App = function () { 
            this[propertyKey] = descriptor.value;
        };
    } else {
        global.App[propertyKey] = descriptor.value;
    }
    
    return descriptor;
}

这样的事情可能会奏效。

【讨论】:

  • 没用,global.App 在每一步之后都是未定义的.. 仍在试图找出原因.. 基本上我在每次分配后都放了一个 console.log 并且它产生未定义跨度>
  • 好的,也许将分配部分分开以确保其已定义。
【解决方案2】:

在 SO 徘徊了一段时间后,我找到了解决方法......也许我缺乏 TS/JS 知识,无法确切知道我想在这里做什么,但无论如何,我的解决方案是注册每个任务装饰然后在index.js 上我得到这些任务并将它们注册到global.App 函数上。

类似的东西

task.ts

export const TaskRegistry = {};

 export const Task = (target, propertyKey, descriptor) => {
   const originalMethod = descriptor.value;
   descriptor.value = (...args) => originalMethod.apply(target, args);

   TaskRegistry[propertyKey] = descriptor.value;

   return descriptor;
 };

index.js

// eslint-disable-next-line func-names
global.App = function () {
   // eslint-disable-next-line consistent-this
   const self = this;

   Object.keys(TaskRegistry).forEach((key) => {
     self[key] = TaskRegistry[key];
   });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-05
    • 2015-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多