Rozważ to:
var x = function() {
return arguments;
}
console.log(x() === x());
To fałszywe, bo to nie jest to samo arguments
przedmiot: to (dla każdego invokation z x
) w nowo wybudowanym obiekcie, który ma wartości wszystkich params przechowywanych wewnątrz. Jednak ma ona właściwości arguments
:
var y = x([]);
console.log(y instanceof Object); // true
console.log(y instanceof Array); // false
console.log(y.length); // 1
console.log(y.callee + ''); // function() { return arguments; }
jeszcze coś więcej do tego. Oczywiście, przedmioty wysyłane do funkcji jako jej params nie będą zbierane przez GC jeśli arguments
zwrócone są:
var z = x({some: 'value'});
console.log(z[0]); // {some:'value'}
To normalne: mimo wszystko, można uzyskać podobny wynik, oświadczając jakiś lokalny obiekt wewnątrz funkcji, przypisywanie wartość pierwszego parametru funkcji jako własności obiektu "0", a następnie zwrócenie tego obiektu. W obu przypadkach obiekt, o którym mowa, będzie nadal "w użyciu", więc nie ma sprawy, jak sądzę.
Ale co z tym?
var globalArgs;
var returnArguments = function() {
var localArgs = arguments;
console.log('Local arguments: ');
console.log(localArgs.callee.arguments);
if (globalArgs) { // not the first run
console.log('Global arguments inside function: ');
console.log(globalArgs.callee.arguments);
}
return arguments;
}
globalArgs = returnArguments('foo');
console.log('Global arguments outside function #1: ');
console.log(globalArgs.callee.arguments);
globalArgs = returnArguments('bar');
console.log('Global arguments outside function #2: ');
console.log(globalArgs.callee.arguments);
wyjściowa:
Local arguments: ["foo"]
Global arguments outside function #1: null
Local arguments: ["bar"]
Global arguments inside function: ["bar"]
Global arguments outside function #2: null
Jak widać, jeśli wrócisz arguments
obiekt i przypisać go do jakiejś zmiennej wewnątrz funkcji jego callee.argument
punktów własności do tego samego zestawu danych, jak sama arguments
; to znów jest oczekiwane. Ale poza funkcją variable.callee.arguments
jest równa null (nie niezdefiniowana).
Dziwną rzeczą w 'argumentach' jest to, że nazwane parametry są faktycznie ** aliasami ** dla elementów pseudo-tablicy. Spróbuj! Jeśli zmienisz 'argumenty [0]', zmieni się również 'a'! Nie sądzę, że z tego powodu przecieka. – Pointy
Naprawdę? Myślałem, że jest odwrotnie: 'arguments [0]' jest aliasem dla 'a' :-) Algorytm opisany w specyfikacji wskazuje, że indeksy' argumentów' były ustawiaczami i pobierającymi z "ParameterMap" i link do rekordu środowiska inwokacji - możliwy powód do wycieku imho. Dlatego też pytam o rzeczywiste implementacje ... – Bergi
Cóż, myślę, że jest to rodzaj tajemnicy, która jest aliasem, dla którego :-) Myślę, że ponieważ obiekt argumentów jest w zasadzie ** jest ** zestaw parametrów, nie potrzebuje odniesienia do zamknięcia ani niczego, więc inne niż pamięć, której używa bezpośrednio nie "przypina" niczego innego. To tylko przeczucie i nie znam prawdziwej historii. – Pointy