Czy jest jakiś sposób, aby odnieść się do obiektu funkcyjnego, w którym obecnie wykonujesz? Jeśli nie jest to metoda jakiegokolwiek obiektu lub nie zostanie wywołana .call() lub .apply(), wskaźnik this jest prawdopodobnie window, a nie obiekt funkcyjny.

Często używam takiego wzorca projektu, jak dla zmiennych globalnych, które chcę przełączyć do konkretnej funkcji, ponieważ utrzymuje je z najwyższej przestrzeni nazw:

function generateRandom() {
    if (!generateRandom.prevNums) {    
        generateRandom.prevNums = {};    // generateRandom.prevNums is a global variable
    }
    var random;
    do {
        random = Math.floor((Math.random() * (99999999 - 10000000 + 1)) + 10000000);
    } while (generateRandom.prevNums[random])
    generateRandom.prevNums[random] = true;
    return(random.toString());
}

Ale wolałbym nie trzeba przeliterować nazwy funkcji za każdym razem, gdy chcę użyć zmiennej skrócenia do tego obiektu. Jeśli nazwa funkcji kiedykolwiek się zmienia, istnieje wiele miejsc do zmiany nazwy.

Czy jest jakiś sposób, aby uzyskać aktualnie wykonujący obiekt funkcyjny?

1
jfriend00 12 grudzień 2011, 12:04

3 odpowiedzi

Najlepsza odpowiedź

Nie sądzę, żeby w żaden sposób ma jakiś sposób, aby zrobić dokładnie to, o co pytasz, ale zamiast tego można użyć zamknięcia dla lokalnych zmiennych statycznych funkcji.

Możesz łatwo osiągnąć za pomocą IIFE:

var generateRandom = (function() {
    //any function's static variables go here
    var prevNums = {};

    return function() {
        //function code goes here
        var random;
        do {
            random = Math....
        }

        prevNums[random] = true; 

        return random.toString();
    };
})();
1
Jani Hartikainen 12 grudzień 2011, 08:08

Chcesz arguments.callee. Z MDN - Callee:

callee jest właściwością obiektu arguments. Może być używany do odnoszenia się do aktualnie wykonywalnego funkcji wewnątrz korpusu funkcji tej funkcji. Jest to na przykład przydatne, gdy nie znasz nazwy tej funkcji, która jest na przykład w przypadku anonimowych funkcji.

Na przykład:

> foo = function() { console.log(arguments.callee); };
> bar = function() { foo() };
> bar();
function () { console.log(arguments.callee) }

Myślę jednak, że jest to przestarzały. Powyższy link mówi: "5. edycja ECMAScript zabrania stosowania argumentów.callee () w trybie ścisłym."

1
a paid nerd 12 grudzień 2011, 08:18

Cóż, ty może użyj arguments.callee() ...

https://developer.mozilla.org/en/javascript/reference/functions_and_function_scope/arguments/callee.

Z MDN:

Opis

Callee jest właściwością obiektu argumentów. Może być używany do odwołania do aktualnie wykonywania funkcji w ciele funkcyjnej funkcja. Jest to na przykład przydatne, gdy nie znasz nazwy Ta funkcja, która jest na przykład w przypadku anonimowych funkcji.

Uwaga: Należy unikać przy użyciu argumentów.callee () i po prostu podaj każdą funkcję (wyrażenie) nazwę.

ALE...

To, czego naprawdę chcesz, są prototypami JavaScript.

function RandomSomethingGenerator()
{
   this.prevNums = {};
}

RandomSomethingGenerator.prototype.generate = function() { 
    var random;
    do {
        random = Math.floor((Math.random() * (99999999 - 10000000 + 1)) + 10000000);
    } while (this.prevNums[random])
    this.prevNums[random] = true;
    return(random.toString());
};

Dlaczego to mówię?

1.) Ubijasz globalną przestrzeń wszystkimi funkcjami.

2.) Nawet jeśli lubisz sugestię Jani, i chcesz "statyczne" funkcję, jak teraz, moja sugestia byłaby taka sama, ale z twistem: Utwórz swoją funkcję globalną i owinąć instancję obiektu (zbudowany Prototyp) wewnątrz zamknięcia i zadzwoń do niego (tak, zasadniczo zrób sobie singleton).

Jak w tym (przystosowany z odpowiedzi Jana):

var randomSomething = (function() {
    var randomSomethingGenerator = new RandomSomethingGenerator();

    return function() {
        randomSomethingGenerator.generate();
    };
})();
1
Steve 12 grudzień 2011, 08:28