技术频道导航
HTML/CSS
.NET技术
IIS技术
PHP技术
Js/JQuery
Photoshop
Fireworks
服务器技术
操作系统
网站运营

赞助商

分类目录

赞助商

最新文章

搜索

JavaScript函数表达式与函数声明的差异及注意事项

作者:admin    时间:2022-6-9 17:46:9    浏览:

函数声明和函数表达式是使用function关键字创建函数的两种方法,在本文中,我将介绍这两种方法的差异,以及使用它们时的注意事项。

函数表达式与函数声明

让我们举一个例子来说明差异——我们创建一个对数字求和的函数的 2 个版本:

function sumA(a, b) {
  return a + b;
}
(function sumB(a, b) {
  return a + b;
});
sumA(1, 2); // ???
sumB(1, 2); // ???

一种情况,你可以像往常一样定义函数(sumA函数)。另一种情况,函数被放置在一对括号中(sumB函数)。

如果你调用sumA(1, 2)sumB(1, 2)会发生什么?

正如预期的那样,sumA(1, 2)只需返回1和2数字的总和: 3。而,调用sumB(1, 2)会引发错误Uncaught ReferenceError: sumB is not defined

解释是sumA使用函数声明创建的,它在当前范围内创建一个函数变量(与函数名称相同)。但是sumB是使用函数表达式创建的(它被包裹在括号中),它不会在当前范围内创建函数变量。

如果要访问使用函数表达式创建的函数,可以将函数对象保存到变量中:

const sum = (function sumB(a, b) {
  return a + b;
});
sum(1, 2); // => 3

如何区分函数声明和函数表达式

下面是关于如何区分函数声明和函数表达式的简单方法:

如果语句以function关键字开头,则为函数声明,否则为函数表达式。

// 函数声明: 用 `function` 关键词开始
function sumA(a, b) {
return a + b;
}
// 函数表达式: 不以 `function` 关键词开始
const mySum = (function sumB(a, b) {
return a + b;
});
// 函数表达式: 不以 `function` 关键词开始
[1, 2, 3].reduce(function sum3(acc, number) {
return acc + number
});

从更高的角度来看,函数声明对于创建独立函数很有用,但函数表达式作为回调很好。

现在,让我们更深入地研究函数声明和函数表达式的使用。

2、函数声明

在前面的示例中已经看到的,sumA是一个函数声明:

function sumA(a, b) {
  return a + b;
}
sumA(4, 5); // => 9

当语句包含关键字后跟函数名、一对带参数的括号以及用一对花括号括起来的函数体时,就是函数声明。function(param1, param2, paramN){ }

函数声明创建了一个函数变量——一个与函数名同名的变量(例如前面例子的sumA)。函数变量可以在当前范围内(函数声明之前和之后)访问,甚至可以在函数的范围内访问。

函数变量通常用于调用函数或将函数对象传递给其他函数(传递给高阶函数)。

例如,我们编写一个函数sumArray(array),对数组的项进行递归求和(该数组可以包含数字或其他数组):

sumArray([10, [1, [5]]]); // => 16
function sumArray(array) {
  let sum = 0;
  for (const item of array) {
    sum += Array.isArray(item) ? sumArray(item) : item;
  }
  return sum;
}
sumArray([1, [4, 6]]); // => 11

function sumArray(array) { ... }是一个函数声明。

包含函数对象的函数变量sumArray在当前范围内可用:在函数声明之前sumArray([10, [1, [5]]])和之后sumArray([1, [4, 6]]),以及在函数本身的范围内sumArray(item)(允许递归调用)。

由于提升,函数变量在函数声明之前可用。

函数声明的注意事项

函数声明语法的作用是创建独立函数。函数声明应在全局范围内或直接在其他函数的范围内:

// 好!
function myFunc1(param1, param2) {
  return param1 + param2;
}
function bigFunction(param) {
  // 好!
  function myFunc2(param1, param2) {
    return param1 + param2;
  }
  const result = myFunc2(1, 3);
  return result + param;
}

出于同样的原因,不建议在条件 (if) 和循环 ( while, for)中使用函数声明:

// 不好!
if (myCondition) {
  function myFunction(a, b) {
    return a * b;
  }
} else {
  function myFunction(a, b) {
    return a + b;
  }
}
myFunction(2, 3);

使用函数表达式更好地执行有条件地创建函数。

3、函数表达式

function关键字在表达式内创建函数(有或没有名称)时,就是函数表达式。

以下是使用表达式创建的函数的示例:

const sum = (function sumB(a, b) {
  return a + b;
});
const myObject = {
  myMethod: function() {
    return 42;
  }
};
const numbers = [4, 1, 6];
numbers.forEach(function callback(number) {
  console.log(number);
  // logs 4
  // logs 1
  // logs 1
});

在函数表达式中创建了两种函数:

  • 如果表达式中的函数没有名称,例如function() { return 42 },那么这是一个匿名函数表达式。
  • 如果函数有名字,例如在前面的例子中的sumBcallback,那么这是一个命名函数表达式。

函数表达式的注意事项

函数表达式非常适合作为条件创建的回调或函数:

// 有条件地创建函数
let callback;
if (true) {
  callback = function() { return 42 };
} else {
  callback = function() { return 3.14 };
}
// 作为回调使用函数
[1, 2, 3].map(function increment(number) {
  return number + 1;
}); // => [2, 3, 4]

如果你创建了命名函数表达式,请注意函数变量仅在创建的函数范围内可用:

const numbers = [4];
numbers.forEach(function callback(number) {
  console.log(callback); // logs function() { ... }
});
console.log(callback); // ReferenceError: callback is not defined

callback是一个命名函数表达式,因此callback函数变量仅在callback()函数范围内可用,而在外部不可用。

但是,如果将函数对象存储到常规变量中,则可以在函数范围内外从该变量访问函数对象:

const callback = function(number) {
  console.log(callback); // logs function() { ... }
};
const numbers = [4];
numbers.forEach(callback);
console.log(callback); // logs function() { ... }

4、总结

根据你使用function关键字创建函数的方式,你可以通过两种方式创建函数:函数声明和函数表达式。

当你使用function关键字开始语句时是函数声明,函数声明对于创建独立的通用函数很有用。

如果语句不以function关键字开头,那么这是一个函数表达式,使用函数表达式创建的函数对于按条件创建回调或函数很有用。

相关文章

相关文章
    x
    • 站长推荐
    /* 左侧显示文章内容目录 */