var functionName = function () {} против функции functionName () {} - PullRequest
6466 голосов
/ 03 декабря 2008

Я недавно начал поддерживать чужой код JavaScript. Я исправляю ошибки, добавляю функции, а также пытаюсь привести в порядок код и сделать его более согласованным.

Предыдущий разработчик использовал два способа объявления функций, и я не могу понять, есть ли причина этого или нет.

Два способа:

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

Каковы причины использования этих двух разных методов и каковы плюсы и минусы каждого? Можно ли что-то сделать одним методом, а другим - нет?

Ответы [ 37 ]

2 голосов
/ 17 декабря 2018

Первым является Выражение анонимной функции , а вторым является Объявление функции . У анонимных функций просто нет имени. Основным различием между выражением анонимной функции и оператором функции является имя функции.

Именованные функции против Анонимные функции

Анонимная функция быстро и легко вводится, и многие библиотеки и инструменты поддерживают этот идиоматический стиль кода. Однако анонимные функции имеют некоторые недостатки :

  • Удобочитаемость: анонимные функции опускают имя, которое может вызвать менее читаемый код.

  • Отладка: анонимные функции не имеют полезного имени в трассировке стека, что может усложнить отладку.

  • Self-Reference: что если функция должна ссылаться на себя, например, для рекурсии.

Выражение функции именования:

Предоставление имени для выражения вашей функции довольно эффективно устраняет все эти недостатки и не имеет ощутимых недостатков. Лучше всего всегда называть выражения вашей функции:

setTimeout(function timeHandler() { // <-- look, a name here!
  console.log("I've waited 1 second");
}, 1000);

Именование IIFE (выражение для немедленного вызова функции) :

(function IIFE(str) { // <-- look, always name IIFEs!
  console.log(str); // "Hello!"
})('Hello!');

Для функций, назначенных переменной, наименование функции, в этом случае, не очень распространено и может вызвать путаницу, в этом случае, функция стрелки может быть лучшим выбором.

2 голосов
/ 15 июля 2018

Это называется выражением функции:

var getRectArea = function(width, height) {
    return width * height;
};

console.log("Area of Rectangle: " + getRectArea(3,4));
// This should return the following result in the console: 
// Area of Rectangle: 12

Это называется объявлением функции:

var w = 5;
var h = 6;

function RectArea(width, height) {  //declaring the function
  return area = width * height;
}                                   //note you do not need ; after }

RectArea(w,h);                      //calling or executing the function
console.log("Area of Rectangle: " + area);
// This should return the following result in the console: 
// Area of Rectangle: 30

Надеюсь, это поможет объяснить, в чем разница между выражением функции и объявлением функции и как их использовать. Спасибо.

1 голос
/ 18 октября 2018

Следует отметить один важный момент: -

пусть есть две функции: -

sum(1,2);

const sum = function(first, second) {
  return first + second;
}

В вышеприведенном случае это даст ошибку, что сумма не определена, но

sum(1,2);

function sum(first, second) {
  return first + second;
}

Эта функция не выдаст ошибку, так как Подъем будет иметь место в этом случае.

1 голос
/ 15 мая 2018

Выражение в JS : что-то, что возвращает значение
Пример: Попробуйте выполнить следующие действия в консоли Chrome:

a = 10
output : 10

(1 + 3)
output = 4

Декларация / Заявление : что-то, что не возвращает значение
Пример:

if (1 > 2) {
 // do something. 
}

здесь (1> 2) - это выражение, но утверждение «если» - нет. Это ничего не возвращает.


Точно так же у нас есть объявление функции / оператор против выражения функции
Давайте возьмем пример:

// test.js

var a = 10;

// function expression
var fun_expression = function() {
   console.log("Running function Expression");
}

// funciton expression

function fun_declaration() {
   console.log("Running function Statement");
}

Важно: Что происходит, когда движки JavaScript запускают вышеуказанный файл js.

  • При запуске этого js произойдут следующие вещи:

    1. В памяти будут созданы переменные 'a' и 'fun_expression'. И память будет создана для выражения функции 'fun_declaration'
    2. 'a' будет присвоен 'undefined'. 'fun_expression' будет присвоено значение 'undefined'. 'fun_declaration' будет в памяти полностью.
      Примечание: вышеприведенные шаги 1 и 2 называются «контекст выполнения - фаза создания» .

Теперь предположим, что мы обновили js до.

// test.js

console.log(a)  //output: udefined (No error)
console.log(fun_expression)  // output: undefined (No error)
console.log(fun_expression()) // output: Error. As we trying to invoke undefined. 
console.log(fun_declaration()) // output: running function statement  (As fun_declaration is already hoisted in the memory). 

var a = 10;

// function expression
var fun_expression = function() {
   console.log('Running function expression')
}

// function declaration

function fun_declaration() {
   console.log('running function declaration')
}

console.log(a)   // output: 10
console.log(fun_expression()) //output: Running function expression
console.log(fun_declaration()) //output: running function declaration

Вывод, упомянутый выше в комментариях, должен быть полезен для понимания различий между выражением функции и оператором / объявлением функции.

1 голос
/ 08 марта 2018

Я предпочитаю определять функцию как переменную:

let first = function(x){
   return x[0];
}

Вместо:

function first(){
    ....
}

Потому что я могу использовать выражения и декораторы при определении функции. Например:

let safe = function(f){
  try {f()...}
}
let last = safe(function(x){return x[0]}).

Также с ES6 намного короче:

 let last = x => x[0]
 ...........
 function last(x){
     return x[0];
 }
......

let last = safe(x => x[0]);
0 голосов
/ 01 февраля 2019

Подъемное поведение между объявлениями функций и выражениями важно, но между ними есть еще одно различие:

функции в условных выражениях

Общая практика, рекомендуемая MDN , заключается в использовании функциональных выражений вместо объявлений внутри операторов if. Из приведенного в ссылке примера объявления функций внутри операторов if будут вести себя одинаково в Chrome и Firefox, но не в Safari.

Отказ от ответственности: macOS не может запустить Microsoft Edge, поэтому я не могу проверить.

// function declaration example

var hoisted = "foo" in this;

console.log(`'foo' name ${hoisted ? "is" : "is not"} hoisted. typeof foo is ${typeof foo}`);

if (false) {
  function foo() {
    return 1;
  }
}

// In Chrome: 
// 'foo' name is hoisted. typeof foo is undefined

// In Firefox:
// 'foo' name is hoisted. typeof foo is undefined

// In Safari:
// 'foo' name is hoisted. typeof foo is function

Преобразование foo в выражение функции даст согласованные результаты во всех трех веб-браузерах.

// function expression example

var hoisted = "foo" in this;

console.log(`'foo' name ${hoisted ? "is" : "is not"} hoisted. typeof foo is ${typeof foo}`);

if (false) {
  var foo = function() {
    return 1;
  }
}

// In Chrome: 
// 'foo' name is hoisted. typeof foo is undefined

// In Firefox:
// 'foo' name is hoisted. typeof foo is undefined

// In Safari:
// 'foo' name is hoisted. typeof foo is undefined
0 голосов
/ 02 января 2019

Другое различие между обеими функциями заключается в том, что functionOne может использоваться как переменная, которая может содержать несколько функций внутри, а functionTwo содержит некоторый блок кода, который выполняется все при вызове. Пожалуйста, проверьте ниже:

   var functionOne = (function() {
      return {

         sayHello: function(){
                console.log('say hello')

         },
         redirectPage:function(_url){
                window.location.href = _url;
         }

      }
})();

У вас есть выбор, какую функцию вызывать. например, functionOne.sayHello или functionOne. redirectPage. И если вы вызовете functionTwo, тогда будет выполнен весь блок кода.

...