【问题标题】:Function reassignment in JavaScriptJavaScript 中的函数重新分配
【发布时间】:2019-10-19 18:53:25
【问题描述】:

我有一个用 javascript 编写的函数,它跟踪传递给它的函数的递归调用。

function trace(fn){
    let indent = 0

    return function tracedFunction(args){
        console.log("| ".repeat(indent)+"|--"+fn.name,args)
        indent += 1
        let value = fn(args)
        console.log("| ".repeat(indent)+"|--"+"return",value)
        indent -= 1
        return value
    }

}

function fibo(num){
    if(num==0 || num==1)
        return 1;
    return fibo(num-1)+fibo(num-2);
}


fibo = trace(fibo)
fibo(4)

这给出了以下输出

|--fibo 4
| |--fibo 3
| | |--fibo 2
| | | |--fibo 1
| | | | |--return 1
| | | |--fibo 0
| | | | |--return 1
| | | |--return 2
| | |--fibo 1
| | | |--return 1
| | |--return 3
| |--fibo 2
| | |--fibo 1
| | | |--return 1
| | |--fibo 0
| | | |--return 1
| | |--return 2
| |--return 5
5

我的问题如下

  1. fibo = trace(fibo) 行发生了什么?

    • 是不是重新定义了fibo函数?
    • B 是否在全局范围内创建了一个名为fibo 的变量并将trace(fibo) 分配给它?

    • 如果 (A) 是这种情况,这样做是一个好习惯吗?有没有其他方法可以做到这一点?

【问题讨论】:

  • 它只是简单地给一个变量赋值。

标签: javascript closures higher-order-functions


【解决方案1】:

您在这里所做的称为“装饰器”。这是 python 中一个非常普遍且广泛使用的特性,但在 JS 中,经过大约 5 年的工作,它们仍然在排队。转译器和 TypeScript 确实支持装饰器,但仍然无法装饰函数,只能装饰方法,因此您必须将 fibo 包装在一个类中才能使其工作(如果您问我,这看起来很傻):

function trace(target, propertyKey, descriptor) {
    let indent = 0;
    let fn = target[propertyKey];

    descriptor.value = function tracedFunction(args){
       etc
     }
}

class Dummy {
    @trace
    static fibo(num) {
        if (num == 0 || num == 1)
            return 1;
        return Dummy.fibo(num - 1) + Dummy.fibo(num - 2);
    }
}

Dummy.fibo(4)

Typescript playground

在装饰器语法标准化并正确实现之前,装饰函数的唯一方法是编写函数 - 应用装饰器并重新分配给原始名称。

要回答您的问题,它是 A 和 B - 函数是 javascript 中的第一类,因此将函数值分配给变量会将变量绑定到该函数,并且旧函数会丢失。函数声明语法function foo() {...} 基本上只是var foo = function .... 的快捷方式(最多一些令人讨厌的提升细节)。

【讨论】:

  • 嗨,现在这很有意义。我曾认为重新分配功能是一种不好的做法。有没有办法在trace 函数本身中包含这个逻辑fibo = trace(fibo)
  • @AlanLal:一般来说,不,你不能。这就是为什么装饰器只能用于对象方法而不是函数的原因之一。
猜你喜欢
  • 2014-01-30
  • 2011-04-30
  • 2013-12-15
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 2017-12-13
  • 1970-01-01
  • 2019-06-12
相关资源
最近更新 更多