Существует ли использование arguments.callee без хорошей альтернативы?

Существует много заблуждений относительно arguments.callee, и я пытаюсь понять, существуют ли случаи использования, когда его действительно нельзя заменить жизнеспособной альтернативой строгого режима ES5. .

В документации MDN arguments.callee они указывают на использование аргументов. callee без хорошей альтернативы со следующим примером кода ниже:

function createPerson (sIdentity) {
    var oPerson = new Function("alert(arguments.callee.identity);");
    oPerson.identity = sIdentity;
    return oPerson;
}

var john = createPerson("John Smith");

john();

Они включили ссылку на ошибку, чтобы показать, что в некоторых случаях аргумент. callee нельзя заменить кодом, соответствующим строгому режиму ES5.

Но для понимания код, который они использовали в качестве примера, можно заменить следующей альтернативой строгий режим:

"use strict";

function createPerson(sIdentity) {
    var oPerson = function () {
        alert(oPerson.identity);
    };

    oPerson.identity = sIdentity;
    return oPerson;
}

var john = createPerson("John Smith");

john();

С учетом сказанного, действительно существуют алгоритмы, в которых нельзя заменить arguments.callee?

ПОДАРОК

Чтобы выиграть награду, я хочу, чтобы ответ содержал использование arguments.callee, где было бы гораздо более неясно или невозможно использовать другое решение.

В примере с MDN версия, которую я написал в качестве альтернативы, не меняет использование этого фрагмента кода.


person sergiogarciadev    schedule 21.05.2014    source источник
comment
Возможный дубликат Arguments.callee устарел - что следует использовать вместо этого?   -  person Tomas    schedule 25.05.2014
comment
Это не совсем дубликат. Я изучаю, действительно ли есть места, где мы должны использовать arguments.callee, а не альтернативы. Каждый кусок кода, который я получил, я мог бы использовать в качестве альтернативы, но я вижу много людей, спорящих об устаревании arguments.callee, и я не вижу для этого причин. Чтобы использовать arguments.callee, мы должны пройтись по стеку, и он медленный на всех языках, которые я знаю.   -  person sergiogarciadev    schedule 26.05.2014


Ответы (3)


Вот вариант использования: сохраните переменную для встроенного обработчика событий (который может исходить из сгенерированного/шаблонного кода), не загрязняя глобальное пространство имен или DOM и не рискуя другими конфликтами имен:

<button onclick="var f=arguments.callee;alert(f.i=(f.i||0)+1)">CLICK</button>

Демонстрация

Теперь предположим, что это не законное использование. Конечно, по-настоящему законных нет, иначе arguments.callee не уволили бы.

person Denys Séguret    schedule 26.05.2014
comment
Умное использование, встроенные обработчики событий вводят динамическую типизацию и заставляют браузеры проходить через обручи, что является еще одной причиной не использовать их. - person Benjamin Gruenbaum; 26.05.2014
comment
Использование this приводит к тому же результату, не так ли? jsbin.com/bisitiru/2/edit - person sergiogarciadev; 27.05.2014
comment
@SergioGarcia Да, именно поэтому я уточнил, не загрязняя DOM: использование this добавляет свойство к элементу, и у вас есть теоретический риск возникновения коллизии с другим подобным обработчиком событий. Решение, которое я даю, также позволяет одной и той же функции быть независимой от ее использования и, например, внедряться более чем в один обработчик событий: jsbin.com/nepejo/2/edit - person Denys Séguret; 27.05.2014

Когда вы создаете функцию динамически (из строки), она не может "захватывать" какие-либо внешние переменные, как это делает обычное замыкание.

Итак, пример MDN имитирует закрытие, делая значение доступным через arguments.callee. Другого пути без изменения сигнатуры функции действительно нет.

person Scott Rippey    schedule 23.05.2014
comment
Я просто положил закрытие, чтобы принудительно использовать strict. - person sergiogarciadev; 23.05.2014
comment
Я обновил свой ответ, чтобы он был немного более ясным... Закрытие - это единственное, что не может быть сделано динамической функцией, поэтому требуется arguments.callee - person Scott Rippey; 24.05.2014

Боюсь, вы неправильно поняли пример. Это означает, что используйте конструктор функций, альтернативы arguments.callee нет. Скажем, код ниже

function createPerson (sIdentity) {
    var oPerson = new Function("alert(oPerson.identity);");
    oPerson.identity = sIdentity;
    return oPerson;
}

var john = createPerson("John Smith");

john();

неправильно

person xlhuang    schedule 26.05.2014
comment
Да, я понимаю ваш аргумент, но есть ли практический пример, где это необходимо? Это то, что я ищу. Может быть, парсер шаблонов и генератор вывода или что-то в этом роде. Я вижу, что люди утверждают, что arguments.callee необходимо, но без веских причин. - person sergiogarciadev; 27.05.2014
comment
Просто для справки, вот еще одна демонстрация использования arguments.callee: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ - person sergiogarciadev; 27.05.2014