alla gör ungefär samma sak, med några subtila skillnader:
det finns en skillnad mellan funktionsnamnet och variabeln funktionen tilldelas. Funktionsnamnet kan inte ändras, medan variabeln funktionen är tilldelad till kan omplaceras. Funktionsnamnet kan endast användas i funktionens kropp. Om du försöker använda den utanför funktionen resulterar det i ett fel (eller undefined
om funktionsnamnet tidigare deklarerats via ett var
– uttalande)., Till exempel:
var y = function x() {};alert(x); // throws an error
funktionsnamnet visas också när funktionen serialiseras via Function
s toString-metod.
å andra sidan begränsas variabeln som funktionen är tilldelad till endast av dess omfattning, vilket garanteras inkludera det område där funktionen deklareras.
som det 4: e exemplet visar kan funktionsnamnet skilja sig från den variabel som funktionen är tilldelad till. De har ingen relation till varandra. En funktionsdeklaration skapar också en variabel med samma namn som funktionsnamnet., Till skillnad från de som definieras av funktionsuttryck kan funktioner som definieras av funktionsdeklarationer nås med deras namn i det område de definierades i:
en funktion som definieras av ’new Function'
har inget funktionsnamn. Men i Spidermonkey JavaScript-motorn visar den serialiserade formen av funktionen som om den har namnet ”anonym”. Till exempelalert(new Function())
utgångar:
function anonymous() {}
eftersom funktionen faktiskt inte har ett namn äranonymous
inte en variabel som kan nås inom funktionen., Till exempel skulle följande resultera i ett fel:
var foo = new Function("alert(anonymous);");foo();
Till skillnad från funktioner som definieras av funktionsuttryck eller av konstruktören Function
kan en funktion som definieras av en funktionsdeklaration användas före själva funktionsdeklarationen. Till exempel:
foo(); // alerts FOO!function foo() { alert('FOO!');}
en funktion som definieras av ett funktionsuttryck eller av en funktionsdeklaration ärver det aktuella tillämpningsområdet. Det vill säga funktionen bildar en stängning., Å andra sidan ärver inte en funktion som definieras av en Function
konstruktör något annat tillämpningsområde än det globala tillämpningsområdet (som alla funktioner ärver).
funktioner som definieras av funktionsuttryck och funktionsdeklarationer tolkas endast en gång, medan de som definieras av konstruktörenFunction
inte är det. Det vill säga, funktionskroppssträngen som skickas till konstruktören Function
måste analyseras varje gång konstruktören heter., Även om ett funktionsuttryck skapar en stängning varje gång, återställs inte funktionskroppen, så funktionsuttryck är fortfarande snabbare än ” new Function(...)
”. Därför bör konstruktören Function
I allmänhet undvikas när det är möjligt.
det bör dock noteras att funktionsuttryck och funktionsdeklarationer som är kapslade inom den funktion som genereras genom att tolka en Function constructor
sträng inte tolkas upprepade gånger. Till exempel:
en funktionsdeklaration är mycket lätt (och ofta oavsiktligt) förvandlas till ett funktionsuttryck., En funktionsdeklaration upphör att vara en när den antingen:
- blir en del av ett uttryck
- är inte längre ett ”källelement” för en funktion eller själva skriptet. Ett ”källelement” är ett icke-kapslat uttalande i skriptet eller en funktionskropp: