Переназначение функции в JavaScript - PullRequest
0 голосов
/ 19 октября 2019

У меня есть функция, написанная на 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) имеет место, является ли это хорошей практикой? Есть ли другой способ сделать это?

1 Ответ

0 голосов
/ 19 октября 2019

То, что вы здесь делаете, называется «декоратором». Это очень распространенная и широко используемая функция в python, но в JS после 5 лет работы они все еще находятся в очереди. Transpilers и 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

Пока синтаксис декоратора не стандартизирован и не реализован должным образом, единственный способ украсить функцию - это то, как вы ее написали - применить декоратор и переназначитьисходное имя.

Чтобы ответить на ваши вопросы, это и A, и B - функции являются первым классом в javascript, поэтому присвоение значения функции переменной связывает эту переменную с этой функцией, и старая функция теряется. Синтаксис объявления функции function foo() {...} - это просто сокращение для var foo = function .... (вплоть до некоторых неприятных деталей подъема).

...