Niedawno zacząłem utrzymywać kogoś innego użytkownika JavaScript. Naprawiam błędy, dodawanie funkcji, a także próbując sporządzić kod i uczynić go bardziej spójnym.

Poprzedni deweloper używał dwóch sposobów deklarowania funkcji i nie mogę ćwiczyć, jeśli istnieje przyczyna za nim, czy nie.

Na dwa sposoby:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

Jakie są przyczyny korzystania z tych dwóch różnych metod i jakie są zalety i minusy każdego? Czy jest coś, co można zrobić za pomocą jednej metody, której nie można zrobić z drugim?

7316
Richard Garside 3 grudzień 2008, 14:31

23 odpowiedzi

Najlepsza odpowiedź

Różnica polega na tym, że functionOne jest wyrażeniem funkcji i tak zdefiniowany tylko wtedy, gdy linia zostanie osiągnięta, podczas gdy functionTwo jest deklaracją funkcji i jest zdefiniowana, gdy tylko jego otaczająca funkcja lub skrypt zostanie wykonany (z powodu wykonywania < href = "http://adripofjavascript.com/blog/drips/varible-and-Function-HOISTING.HTML" Rel = "NefErrer"> Podnośnik ).

Na przykład wyrażenie funkcji:

// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};

Oraz deklaracja funkcji:

// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

Oznacza to również, że nie można określić warunkowo funkcje przy użyciu deklaracji funkcji:

if (test) {
   // Error or misbehavior
   function functionThree() { doSomething(); }
}

Powyższe faktycznie definiuje functionThree niezależnie od wartości test "s - chyba że obowiązuje use strict, w którym to przypadku po prostu podnosi błąd.

5213
Ben Aston 23 kwiecień 2020, 15:33

Najpierw chcę poprawić Greg: function abc(){} jest zbyt scoped - nazwa abc jest zdefiniowana w zakresie, w którym napotkana jest ta definicja. Przykład:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

Po drugie, możliwe jest połączenie obu stylów:

var xyz = function abc(){};

xyz zostanie zdefiniowany jako zwykle, abc jest niezdefiniowany we wszystkich przeglądarkach, ale Internet Explorer - nie polegają na tym, że jesteś zdefiniowany. Ale zostanie zdefiniowany wewnątrz jego ciała:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

Jeśli chcesz alias funkcje we wszystkich przeglądarkach, użyj tego rodzaju deklaracji:

function abc(){};
var xyz = abc;

W tym przypadku zarówno xyz i abc są aliasami tego samego obiektu:

console.log(xyz === abc); // prints "true"

Jednym z niezwykłych powodów do użycia stylu połączony jest atrybut "Nazwa" obiektów funkcyjnych ( nie jest obsługiwany przez Internet Explorer ). Zasadniczo, gdy definiujesz funkcję jak

function abc(){};
console.log(abc.name); // prints "abc"

Nazwa jest automatycznie przypisana. Ale kiedy to zdefiniujesz

var abc = function(){};
console.log(abc.name); // prints ""

Nazwa jest pusta - stworzyliśmy funkcję anonimową i przypisaliśmy go do pewnej zmiennej.

Kolejnym dobrym powodem użycia stylu połączonego jest użycie krótkiej nazwy wewnętrznej, aby odnieść się do siebie, zapewniając długą niezgodną nazwę dla użytkowników zewnętrznych:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

W powyższym przykładzie możemy zrobić to samo z nazwą zewnętrzną, ale będzie zbyt nieporęczny (i wolniej).

(Em> (Inny sposób na odnoszenie się do siebie jest użycie arguments.callee, który jest nadal stosunkowo długi i nie jest obsługiwany w trybie ścisłym.)

W głębi duszy, javascript traktuje oba oświadczenia inaczej. Jest to deklarację funkcji:

function abc(){}

abc tutaj jest zdefiniowany wszędzie w obecnym zakresie:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

Również podnosi się za pomocą oświadczenia return:

// We can call it here
abc(); // Works
return;
function abc(){}

Jest to wyrażenie funkcji:

var xyz = function(){};

xyz tutaj jest zdefiniowany z punktu przydzielania:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

Deklaracja funkcji a wyrażenie funkcji jest prawdziwym powodem, dla którego istnieje różnica zademonstrowana przez Greg.

Śmieszny fakt:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

Osobiście wolę deklarację "wyrażenia funkcji", ponieważ w ten sposób mogę kontrolować widoczność. Kiedy definiuję funkcję takiej jak

var abc = function(){};

Wiem, że określałem funkcję lokalnie. Kiedy definiuję funkcję takiej jak

abc = function(){};

Wiem, że zdefiniowałem na całym świecie, zapewniając, że nie zdefiniowałem abc w dowolnym miejscu w łańcuchu zakresów. Ten styl definicji jest sprężysty, nawet jeśli jest używany wewnątrz eval(). Podczas gdy definicja

function abc(){};

Zależy od kontekstu i może odgadnąć, gdzie jest faktycznie zdefiniowany, zwłaszcza w przypadku eval() - Odpowiedź brzmi: zależy od przeglądarki.

1983
Merlin 10 październik 2016, 20:38

Mówiąc o kontekstu globalnym, oba, oświadczenie var i FunctionDeclaration na końcu utworzy nieruchomość nieustanne w obiekcie globalnym, ale wartość obu < EM> można nadpisać .

Subtelna różnica między dwoma sposobami jest to, że gdy Zmienna instancja proces Biegnie (przed rzeczywistym wykonaniem kodu) Wszystkie identyfikatory zadeklarowane z var zostaną zainicjowane z undefined, a te używane przez FunctionDeclaration będą dostępne od tego momentu, na przykład:

 alert(typeof foo); // 'function', it's already available
 alert(typeof bar); // 'undefined'
 function foo () {}
 var bar = function () {};
 alert(typeof bar); // 'function'

Przypisanie bar FunctionExpression ma miejsce do czasu wykonania.

Właściwość globalna utworzona przez FunctionDeclaration może być nadpisana bez problemów, podobnie jak wartość zmiennej, np.:

 function test () {}
 test = null;

Inną oczywistą różnicą między dwoma przykładami jest to, że pierwsza funkcja nie ma nazwy, ale druga ma to, co może być naprawdę przydatne podczas debugowania (tj. Sprawdzanie stosu połączeń).

O swojej edytowanym pierwszym przykładzie ({x0}}), jest to zadanie niezarejestrowane, bardzo zachęcałbym, aby zawsze używać słowa kluczowego {x1}}.

Dzięki przypisaniu, bez oświadczenia var, jeśli w łańcuchu zasięgu nie zostanie znaleziony w łańcuchu zakresu, stanie się Urządzeniem Urządzeniem globalnego obiektu.

Również, niezarejestrowane zadania rzucają ReferenceError na ECMAScript 5 pod tryb ścisłego .

Musisz to przeczytać:

Uwaga : Ta odpowiedź została połączona z Kolejne pytanie, w którym głównym wątpliwości i nieporozumienia z OP było to, że identyfikatory zadeklarowane z FunctionDeclaration nie można zastąpić, co nie jest przypadkiem.

154
Community 23 maj 2017, 12:10

Lepsze wyjaśnienie do Odpowiedź Grega

functionTwo();
function functionTwo() {
}

Dlaczego nie ma błędu? Zawsze byliśmy nauczani, że wyrażenia są wykonywane z góry do dołu (??)

Dlatego:

Deklaracje funkcji i deklaracje zmienne są zawsze przenoszone (hoisted) niewidocznie na górę ich zawierającego zakres przez tłumaczenie JavaScript. Parametry funkcji i nazwy zdefiniowane przez języki są oczywiście już tam. Ben Cherry

Oznacza to ten kod:

functionOne();                  ---------------      var functionOne;
                                | is actually |      functionOne();
var functionOne = function(){   | interpreted |-->
};                              |    like     |      functionOne = function(){
                                ---------------      };

Zauważ, że część zadania deklaracji nie została podniesiona. Tylko nazwa jest podnoszona.

, ale w przypadku deklaracji funkcyjnych całe korpus funkcyjny będzie podniósł również :

functionTwo();              ---------------      function functionTwo() {
                            | is actually |      };
function functionTwo() {    | interpreted |-->
}                           |    like     |      functionTwo();
                            ---------------
111
Community 20 czerwiec 2020, 09:12

Inni komentatorzy obejmowali już różnicę semantyczną dwóch wariantów powyżej. Chciałem zauważyć różnicę stylistyczną: tylko zmienność "Przypisanie" może ustawić właściwość innego obiektu.

Często buduję moduły javascript z takim wzorem:

(function(){
    var exports = {};

    function privateUtil() {
            ...
    }

    exports.publicUtil = function() {
            ...
    };

    return exports;
})();

Dzięki temu wzorowi Twoje funkcje publiczne będą korzystać z zadania, podczas gdy Twoje funkcje prywatne wykorzystują deklarację.

(Zauważ również, że zadanie powinno wymagać średnika po oświadczeniu, podczas gdy deklaracja go zabrania.)

97
ROMANIA_engineer 19 październik 2014, 22:24

Ilustracja, kiedy preferować pierwszą metodę drugiego, wtedy, gdy trzeba uniknąć nadrzędnych wcześniejszych definicji funkcji.

Z

if (condition){
    function myfunction(){
        // Some code
    }
}

, Ta definicja myfunction zastąpi jakąkolwiek poprzednią definicję, ponieważ zostanie to zrobione w Parse-Time.

Podczas

if (condition){
    var myfunction = function (){
        // Some code
    }
}

Czy prawidłowe zadanie definiowania {x0}} tylko wtedy, gdy spełniona jest condition.

81
Alireza 29 czerwiec 2017, 14:08

Ważnym powodem jest dodanie jednej i tylko jednej zmiennej jako "root" Twojej przestrzeni nazw ...

var MyNamespace = {}
MyNamespace.foo= function() {

}

Lub

var MyNamespace = {
  foo: function() {
  },
  ...
}

Istnieje wiele technik przestrzeni nazw. Stało się ważniejsze dzięki mnóstwie modułów JavaScript.

Zobacz także Jak zadeklarować przestrzeń nazw w JavaScript?

66
Community 23 maj 2017, 11:55

Dodam własną odpowiedź tylko dlatego, że wszyscy inni obejmowali dokładnie część podnoszenia.

Zastanawiałem się, w jaki sposób jest lepszy od dawna, a dzięki http://jsperf.com teraz I wiedzieć :)

enter image description here

Deklaracje funkcji są szybsze, a to naprawdę ma znaczenie w wersji internetowej DEV? ;)

44
Leon Gaban 1 maj 2015, 15:06

Deklaracja funkcji i wyrażenie funkcji przypisane do zmiennej zachowują się tak samo po ustaleniu wiązania.

Jest jednak różnica w jak i , gdy obiekt funkcyjny jest właściwie związany ze zmienną. Różnica ta wynika z mechanizmu o nazwie zmienna podnośnik w JavaScript.

Zasadniczo wszystkie deklaracje funkcji i deklaracje zmienne są podnoszone na szczycie funkcji , w których następuje deklarację (dlatego mówimy, że JavaScript ma zakres funkcji ).

  • Gdy deklaracja funkcji jest podnoszona, korpus funkcyjny "następuje" Więc kiedy korpus funkcyjny jest oceniany, zmienna zostanie natychmiastowa być związanym z obiektem funkcyjnym.

  • Gdy deklaracja zmiennej jest podnoszona, inicjalizacja ma nie Śledź, ale jest "pozostawiony za". Zmienna jest inicjowana do undefined na początku korpusu funkcji i będzie przypisane przypisane wartość w oryginalnej lokalizacji w kodzie. (Właściwie zostanie on przypisany o wartości w , gdzie następuje oświadczenie o zmiennej o tej samej nazwie.)

Ważne jest również kolejność podnoszenia: Deklaracje funkcji mają pierwszeństwo przed zmiennymi deklaracjami o tej samej nazwie, a ostatnia deklaracja funkcji ma pierwszeństwo przed poprzednimi deklaracjach funkcji o tej samej nazwie.

Kilka przykładów...

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10 }
  return foo; }
bar() // 10

Zmienna foo jest podnoszona na górną część funkcji, zainicjowana do undefined, tak, że !foo jest true, więc foo jest przypisany 10 . foo poza zasięgiem bar nie odgrywa żadnej roli i nie jest nietknięty.

function f() {
  return a; 
  function a() {return 1}; 
  var a = 4;
  function a() {return 2}}
f()() // 2

function f() {
  return a;
  var a = 4;
  function a() {return 1};
  function a() {return 2}}
f()() // 2

Deklaracje funkcji mają pierwszeństwo przed zmiennymi deklaracjami, a Deklaracja ostatniej funkcji "Sticks".

function f() {
  var a = 4;
  function a() {return 1}; 
  function a() {return 2}; 
  return a; }
f() // 4

W tym przykładzie a jest inicjowany za pomocą obiektu funkcyjnego wynikającego z oceny deklaracji drugiej funkcji, a następnie przypisano 4.

var a = 1;
function b() {
  a = 10;
  return;
  function a() {}}
b();
a // 1

Tutaj deklaracja funkcji jest podnoszona pierwsza, deklaracja i inicjowanie zmiennej a. Następnie ta zmienna jest przypisana 10. Innymi słowy: Przypisanie nie przypisuje do zmiennej zewnętrznej a.

36
eljenso 6 luty 2013, 16:29

Jeśli chodzi o koszty utrzymania kodu, wymienione funkcje są bardziej korzystne:

  • Niezależny od miejsca, w którym są one zadeklarowane (ale nadal ograniczone według zakresu).
  • Bardziej odporne na błędy jak warunkowa inicjalizacja (nadal jesteś w stanie zastąpić, jeśli chcesz).
  • Kodeks staje się bardziej czytelny przez przydzielanie lokalnych funkcji oddzielnie funkcjonalności zakresu. Zwykle w zakresie funkcjonalność przechodzi najpierw, a następnie deklaracje lokalnych funkcji.
  • W debugeru wyraźnie widać nazwę funkcji na stosie połączenia zamiast funkcji "anonimowej / ocenianej".

Podejrzewam, że pojawia się więcej profesjonalistów o wymienionych funkcji. A co jest wymienione jako zaletę nazwanych funkcji jest wadą dla anonimowych.

Historycznie, anonimowe funkcje pojawiły się od niezdolności JavaScript jako języka do listy członków z nazwanymi funkcjami:

{
    member:function() { /* How do I make "this.member" a named function? */
    }
}
33
Peter Mortensen 28 grudzień 2015, 19:44

W kategoriach informatyki mówimy o anonimowych funkcjach i nazwanych funkcjach. Myślę, że najważniejszą różnicą jest to, że anonimowa funkcja nie jest związana z nazwą, stąd nazwa anonimowa funkcja. W JavaScript jest to obiekt pierwszej klasy dynamicznie zadeklarowany w czasie wykonywania.

Aby uzyskać więcej informacji na temat anonimowych funkcji i rachunku lambda, Wikipedia jest dobrym startem (http://en.wikipedia.org / Wiki / anonymous_function).

27
ROMANIA_engineer 19 październik 2014, 22:25

Używam zmiennego podejścia do mojego kodu z bardzo konkretnym powodem, którego teoria została pokryta powyżej abstrakcyjnym sposobem, ale przykład może pomóc niektórym osobom takim jak ja, z ograniczoną wiedzą JavaScript.

Mam kod, który muszę uruchomić z 160 niezależnymi marką. Większość kodu znajduje się w udostępnionych plikach, ale materiały specyficzne są w osobnym pliku, jeden dla każdego marki.

Niektóre marki wymagają określonych funkcji, a niektóre nie. Czasami muszę dodać nowe funkcje do wykonania nowych rzeczy specyficzne dla marki. Cieszę się, że mogę zmienić wspólnego zakodowanego, ale nie chcę zmienić wszystkie 160 zestawów plików marki.

Korzystając z składni zmiennej, mogę zadeklarować zmienną (wskaźnik funkcji zasadniczo) w kodzie współdzielonego i przypisać trybną funkcję regulatora, albo ustawiony na NULL.

Jedna lub dwie brandings, które wymagają określonej implementacji funkcji mogą następnie zdefiniować ich wersję funkcji i przypisać to do zmiennej, jeśli chcą, a reszta nic nie robi. Mogę przetestować funkcję NULL przed wykonaniem go w wspólnym kodzie.

Z powyższych komentarzych ludzi, zebrałem, że może być możliwe do ponownego zdefiniowania funkcji statycznej, ale myślę, że roztwór zmiennych jest ładne i jasne.

27
Peter Mortensen 28 grudzień 2015, 20:26

Odpowiedź Grega jest wystarczająco dobra, ale wciąż chciałbym coś dodać, że nauczyłem się teraz obserwować Douglas Crockford's filmy.

Wyrażenie funkcji:

var foo = function foo() {};

Oświadczenie funkcji :

function foo() {};

Oświadczenie funkcji jest tylko skrótem dla var oświadczenie o wartości function.

Więc

function foo() {};

Rozszerza się do

var foo = function foo() {};

Który rozszerza się dalej do:

var foo = undefined;
foo = function foo() {};

I oboje podnosi się na szczyt kodu.

Screenshot from video

26
Community 23 maj 2017, 12:18

@eugenelazutkin daje przykład, w którym on nazwy przypisanej funkcji, aby móc użyć shortcut() jako wewnętrzne odniesienie do siebie. John Resig daje kolejny przykład - kopiowanie funkcji rekurencyjnej przypisanej do innego obiektu w jego Learning Advanced JavaScript samouczek. Podczas przypisywania funkcji do właściwości nie jest tutaj ściśle pytanie, zalecam aktywnie próbując tutorial - Uruchom kod, klikając przycisk w prawym górnym rogu, a kliknij dwukrotnie kod, aby edytować do swoich upodobań.

Przykłady z samouczka: Rekuericzne połączenia w yell():

Testy nie powiedzie się, gdy oryginalny obiekt NINJA zostanie usunięty. (strona 13)

var ninja = { 
  yell: function(n){ 
    return n > 0 ? ninja.yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." ); 

var samurai = { yell: ninja.yell }; 
var ninja = null; 

try { 
  samurai.yell(4); 
} catch(e){ 
  assert( false, "Uh, this isn't good! Where'd ninja.yell go?" ); 
}

Jeśli nazwijasz funkcję, która zostanie nazwana rekurencyjnie, testy przejdą. (strona 14 )

var ninja = { 
  yell: function yell(n){ 
    return n > 0 ? yell(n-1) + "a" : "hiy"; 
  } 
}; 
assert( ninja.yell(4) == "hiyaaaa", "Works as we would expect it to!" ); 

var samurai = { yell: ninja.yell }; 
var ninja = {}; 
assert( samurai.yell(4) == "hiyaaaa", "The method correctly calls itself." );
19
Community 23 maj 2017, 12:34

Kolejna różnica, która nie jest wymieniona w innych odpowiedziach, jest to, że jeśli używasz funkcji anonimowej

var functionOne = function() {
    // Some code
};

I użyj tego jako konstruktora jak w

var one = new functionOne();

Następnie one.constructor.name nie zostanie zdefiniowany. Function.name jest niestandardowy, ale jest obsługiwany przez Firefoksa, Chrome, innych przeglądarek pochodnych webkit i IE 9+.

Z

function functionTwo() {
    // Some code
}
two = new functionTwo();

Możliwe jest pobranie nazwy konstruktora jako ciąg z two.constructor.name.

17
Ingo Kegel 17 styczeń 2013, 08:48

Pierwszy (funkcja dosoming (x)) powinna być częścią notacji obiektu.

Drugi (var doSomething = function(x){ alert(x);}) jest po prostu tworzy funkcję anonimową i przypisując ją do zmiennej, doSomething. Więc dosomanie () zadzwoni do funkcji.

Możesz wiedzieć, co jest wyrażanie funkcji funkcji i funkcji .

Deklaracja funkcji definiuje nazwę o nazwie zmiennej funkcji bez wymagania przydziału zmiennego. Deklaracje funkcji występują jako konstrukty samodzielne i nie mogą być zagnieżdżone w blokach bez funkcji.

function foo() {
    return 3;
}

ECMA 5 (13.0) określa składnię jako
Identyfikator funkcji (FormalparameterList Opt ) {FUNKCJA}

W powyższym stanie nazwa funkcji jest widoczna w swoim zakresie i zakres jego rodzica (w przeciwnym razie byłoby nieosiągalne).

Iw wyrażeniu funkcji

Wyrażenie funkcji definiuje funkcję jako część większej składni wyrażenia (zazwyczaj przypisania zmiennej). Funkcje zdefiniowane przez funkcje Wyrażenia mogą być nazwane lub anonimowe. Wyrażenia funkcji nie powinny uruchamiać się od "funkcji".

// Anonymous function expression
var a = function() {
    return 3;
}

// Named function expression
var a = function foo() {
    return 3;
}

// Self-invoking function expression
(function foo() {
    alert("hello!");
})();

ECMA 5 (13.0) określa składnię jako
Identyfikator funkcji Opt (FormalparameterList Opt ) {FUNKCJA}

16
Peter Mortensen 28 grudzień 2015, 20:29

Jeśli korzystasz z tych funkcji do tworzenia obiektów, otrzymasz:

var objectOne = new functionOne();
console.log(objectOne.__proto__); // prints "Object {}" because constructor is an anonymous function

var objectTwo = new functionTwo();
console.log(objectTwo.__proto__); // prints "functionTwo {}" because constructor is a named function
15
Pawel Furmaniak 25 październik 2013, 16:38

W świetle "Nazywane funkcje pojawiają się w stosach Stosu" Argument, nowoczesne silniki JavaScript są w rzeczywistości zdolne do reprezentowania anonimowych funkcji.

Od tego pisania, V8, Spidermonkey, Chakra i Nitro zawsze odnoszą się do nazwanych funkcji według ich nazw. Prawie zawsze odnoszą się do anonimowej funkcji przez jego identyfikator, jeśli ma jeden.

Spidermonkey może dowiedzieć się o nazwie anonimowej funkcji zwróconej z innej funkcji. Reszta nie może.

Jeśli naprawdę, naprawdę chciałem, aby twój iteratorowi i sukcesowi wywołania zwrotne pojawiły się w śladu, możesz nazwać te też ...

[].forEach(function iterator() {});

Ale w większości nie warto się stresować.

Uprząż (Fiddle)

'use strict';

var a = function () {
    throw new Error();
},
    b = function b() {
        throw new Error();
    },
    c = function d() {
        throw new Error();
    },
    e = {
        f: a,
        g: b,
        h: c,
        i: function () {
            throw new Error();
        },
        j: function j() {
            throw new Error();
        },
        k: function l() {
            throw new Error();
        }
    },
    m = (function () {
        return function () {
            throw new Error();
        };
    }()),
    n = (function () {
        return function n() {
            throw new Error();
        };
    }()),
    o = (function () {
        return function p() {
            throw new Error();
        };
    }());

console.log([a, b, c].concat(Object.keys(e).reduce(function (values, key) {
    return values.concat(e[key]);
}, [])).concat([m, n, o]).reduce(function (logs, func) {

    try {
        func();
    } catch (error) {
        return logs.concat('func.name: ' + func.name + '\n' +
                           'Trace:\n' +
                           error.stack);
        // Need to manually log the error object in Nitro.
    }

}, []).join('\n\n'));

V8

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at e.i (http://localhost:8000/test.js:17:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: j
Trace:
Error
    at j (http://localhost:8000/test.js:20:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: l
Trace:
Error
    at l (http://localhost:8000/test.js:23:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at http://localhost:8000/test.js:28:19
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: n
Trace:
Error
    at n (http://localhost:8000/test.js:33:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: p
Trace:
Error
    at p (http://localhost:8000/test.js:38:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27 test.js:42

Pająk Małpa

func.name: 
Trace:
a@http://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
b@http://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
d@http://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
a@http://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
b@http://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
d@http://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
e.i@http://localhost:8000/test.js:17:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: j
Trace:
j@http://localhost:8000/test.js:20:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: l
Trace:
l@http://localhost:8000/test.js:23:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
m</<@http://localhost:8000/test.js:28:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: n
Trace:
n@http://localhost:8000/test.js:33:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: p
Trace:
p@http://localhost:8000/test.js:38:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1

Czakra

func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at e.i (http://localhost:8000/test.js:17:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at j (http://localhost:8000/test.js:20:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at l (http://localhost:8000/test.js:23:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at Anonymous function (http://localhost:8000/test.js:28:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at n (http://localhost:8000/test.js:33:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at p (http://localhost:8000/test.js:38:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)

Nitro.

func.name: 
Trace:
a@http://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: b
Trace:
b@http://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: d
Trace:
d@http://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: 
Trace:
a@http://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: b
Trace:
b@http://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: d
Trace:
d@http://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: 
Trace:
i@http://localhost:8000/test.js:17:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: j
Trace:
j@http://localhost:8000/test.js:20:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: l
Trace:
l@http://localhost:8000/test.js:23:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: 
Trace:
http://localhost:8000/test.js:28:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: n
Trace:
n@http://localhost:8000/test.js:33:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33

func.name: p
Trace:
p@http://localhost:8000/test.js:38:30
http://localhost:8000/test.js:47:13
reduce@[native code]
global code@http://localhost:8000/test.js:44:33
12
Jackson 13 styczeń 2015, 03:24

Oba są różnymi sposobami określania funkcji. Różnica polega na tym, jak przeglądarka interpretuje i ładuje je w kontekście wykonania.

Pierwszy przypadek jest wyrażeń funkcyjnych, które ładuje tylko wtedy, gdy tłumacz osiąga tę linię kodu. Więc jeśli to zrobisz jak następujące: pojawi się błąd, że funkcja nie jest funkcją .

functionOne();
var functionOne = function() {
    // Some code
};

Powodem jest to, że w pierwszym wierszu nie jest przypisany do funkcjonowania, a tym samym jest niezdefiniowany. Próbujemy zadzwonić do tego jako funkcji, a dlatego otrzymujemy błąd.

W drugiej linii przypisujemy odniesienie do funkcji anonimowej do funkcji.

Drugą sprawą jest deklaracje funkcyjne, które ładuje się przed wykonaniem dowolnego kodu. Więc jeśli podoba Ci się następujące informacje, nie otrzymasz błędu jako obciążenia deklaracji przed wykonaniem kodu.

functionOne();
function functionOne() {
   // Some code
}
11
Peter Mortensen 28 grudzień 2015, 20:42

o wydajności:

Nowe wersje V8 wprowadzono kilka optymalizacji pod kątem, a więc zrobił SpiderMonkey.

Nie ma teraz prawie żadnej różnicy między wyrazem a deklaracją.
Wyrażenie funkcji wydaje się być teraz szybsze teraz.

Chrome 62.0.3202 test Chrome

firefox 55 test Firefox

Chrome Canary 63.0.3225 Chrome Canary Test


Anonymous Wyrażenia funkcjonalne wydaje się mieć lepszą wydajność przeciwko wyrażeniu funkcji Named.


firefox firefox nazwa_anonymous CHROME CANDARY Chrome Canary Named_anonimous chrom Chrome named_anonimous

11
Panos Kal. 28 wrzesień 2017, 05:13

Są one bardzo podobne do niektórych małych różnic, pierwsza jest zmienną, która przypisana do funkcji anonimowej (Deklaracja funkcji), a druga jest normalnym sposobem utworzenia funkcji w JavaScript (Deklaracja anonimowa funkcji), zarówno zużycia, wady i zawodowcy :

1. Wyrażenie funkcji

var functionOne = function() {
    // Some code
};

Wyrażenie funkcji definiuje funkcję jako część większej składni wyrażenia (zazwyczaj przypisania zmiennej). Funkcje zdefiniowane przez funkcje Wyrażenia mogą być nazwane lub anonimowe. Wyrażenia funkcji nie mogą zaczynać się od "funkcji" (stąd nawiasy wokół samodzielnego przykładu poniżej).

Przypisz zmienną do funkcji, oznacza brak podnoszenia, ponieważ wiemy, że funkcje w JavaScript może podnosić, co oznacza, że można je wywołać przed zadeklarowaniem, podczas gdy zmienne muszą zostać ogłoszone przed uzyskaniem dostępu do nich, co oznacza, że w tym przypadku nie możemy Uzyskaj dostęp do funkcji, gdzie zostanie zadeklarowany, może to być sposób, aby napisać funkcje, dla funkcji, które zwracają inną funkcję, ten rodzaj deklaracji może mieć sens, również w ECMA6 i powyżej możesz przypisać to do funkcji strzałki, która Może być używany do wywołania funkcji anonimowych, również ten sposób deklaracji jest lepszym sposobem tworzenia funkcji konstruktora w JavaScript.

2. Deklaracja funkcji

function functionTwo() {
    // Some code
}

Deklaracja funkcji definiuje nazwę o nazwie zmiennej funkcji bez wymagania przydziału zmiennego. Deklaracje funkcji występują jako konstrukty samodzielne i nie mogą być zagnieżdżone w blokach bez funkcji. Pomocne jest pomyślenia o nich jako rodzeństwo ze zmiennych deklaracji. Podobnie jak deklaracje zmienne muszą rozpocząć się od "VAR", Deklaracje funkcji muszą rozpocząć się od "funkcji".

Jest to normalny sposób wywoływania funkcji w JavaScript, funkcja ta może być wywoływana przed zadeklarowaniem go, jak w JavaScript wszystkie funkcje są podnoszone, ale jeśli masz "używać ścisłego", nie podnosi się jak oczekiwano, to dobry sposób Aby zadzwonić do wszystkich normalnych funkcji, które nie są duże w liniach i nie są funkcją konstruktora.

Ponadto, jeśli potrzebujesz więcej informacji o tym, jak działa w JavaScript, odwiedź poniższy link:

https://developer.mozilla.org/en-us/docs/glossary/HOISTING.

10
Alireza 30 lipiec 2017, 04:30

Jest to tylko dwa możliwe sposoby deklaracji funkcji, aw drugim sposobie, możesz użyć funkcji przed deklaracją.

8
Peter Mortensen 28 grudzień 2015, 20:32

new Function() może być użyty do przekazania ciała funkcji w ciągu. A tym samym można go wykorzystać do tworzenia dynamicznych funkcji. Również przekazując skrypt bez wykonywania skryptu.

var func = new Function("x", "y", "return x*y;");
function secondFunction(){
   var result;
   result = func(10,20);
   console.log ( result );
}

secondFunction()
7
SuperNova 10 maj 2016, 07:05