首页 > 应用开发 > Javascript > 何时使用函数表达式与函数声明
在 JavaScript 中创建函数有两种方法:函数表达式和函数声明。 在本文中,我们将讨论何时使用函数表达式与函数声明,并解释它们之间的区别。
函数声明已经使用了很长时间,但函数表达式已经逐渐占据主导地位。 许多开发人员不确定何时使用其中一种,因此他们最终使用了错误的一种。
函数表达式和函数声明之间有一些关键区别。 让我们仔细看看这些差异,以及何时在代码中使用函数表达式与函数声明。
function funcDeclaration() {
return 'A function declaration';}let funcExpression = function () {
return 'A function expression';}
函数声明是在您创建函数并为其命名时。 在编写 function 关键字时声明函数的名称,然后是函数名称。 例如:
let myFunction = function() {
// do something};
如您所见,函数名称 (
myFunction
) 是在创建函数时声明的。
这意味着您可以在定义之前调用该函数。
下面是一个函数声明的例子:
function add (a, b) {
return a + b;};
函数表达式是在您创建函数并将其分配给变量时。 该函数是匿名的,这意味着它没有名称。 例如:
let myFunction = function() {
// do something};
如您所见,该函数已分配给
myFunction
变量。
这意味着您必须先定义该函数,然后才能调用它。
下面是一个函数表达式的例子:
let add = function (a, b) {
return a + b;};
函数表达式和函数声明之间有几个关键区别:
与
let
语句类似,函数声明
被提升到
其他代码的顶部。
函数表达式没有被提升。 这允许他们从定义它们的范围内保留局部变量的副本。
通常,您可以互换使用函数声明和函数表达式。 但有时函数表达式会生成更易于理解的代码,而不需要临时函数名。
那么,什么时候应该使用函数表达式与函数声明呢?
答案取决于您的需求。 如果您需要更灵活的函数或未提升的函数,那么函数表达式是可行的方法。 如果您需要更易读易懂的函数,请使用函数声明。
如您所见,这两种语法是相似的。 最明显的区别是函数表达式是匿名的,而函数声明是有名字的。
今天,当你需要做一些函数表达式不能做的事情时,你通常会使用函数声明。 如果您不需要做任何只能通过函数声明才能完成的事情,那么通常最好使用函数表达式。
当您需要创建递归函数或需要在定义函数之前调用该函数时,请使用函数声明。 根据经验,当您不需要做任何这些事情时,使用函数表达式来获得更简洁的代码。
使用函数声明有几个关键的好处。
函数表达式也有一些好处。
在大多数情况下,很容易找出最适合您需要的函数定义方法。 这些指南将帮助您在大多数情况下快速做出决定。
在以下情况下使用函数声明:
在以下情况下使用函数表达式:
也就是说,在许多情况下,函数表达式的灵活性成为一项强大的资产。
有几种不同的方式可以使函数表达式变得比函数声明更有用。
当您想在函数执行之前为函数提供参数时,使用闭包。
循环通过
NodeList
.
闭包允许您保留其他信息,例如索引,在函数执行后该信息不可用的情况下。
function tabsHandler(index) {
return function tabClickEvent(evt) {
// Do stuff with tab.
// The index variable can be accessed from within here.
};}let tabs = document.querySelectorAll('.tab'),
i;for (i = 0; i < tabs.length; i += 1) {
tabs[i].onclick = tabsHandler(i);}
附加的事件处理程序稍后执行(循环完成后),因此需要一个闭包来保留
for
循环的适当值。
// Bad code, demonstrating why a closure is neededlet i;for (i = 0; i < list.length; i += 1) {
document.querySelector('#item' + i).onclick = function doSomething(evt) {
// Do something with item i
// But, by the time this function executes, the value of i is always list.length
}}
doSomething()
通过从
for
循环中
提取函数,更容易理解为什么会出现问题。
// Bad code, demonstrating why a closure is neededlet list = document.querySelectorAll('.item'),
i,
doSomething = function (evt) {
// Do something with item i.
// But, by the time this function executes, the value of i is not what it was in the loop.
};for (i = 0; i < list.length; i += 1) {
item[i].onclick = doSomething;}
这里的解决方案是将索引作为函数参数传递给外部函数,以便它可以将该值传递给内部函数。 您通常会看到处理函数用于组织内部返回函数所需的信息。
// The following is good code, demonstrating the use of a closurelet list = ['item1', 'item2', 'item3'],
i,
doSomethingHandler = function (itemIndex) {
return function doSomething(evt) {
// now this doSomething function can retain knowledge of
// the index variable via the itemIndex parameter,
// along with other variables that may be available too.
console.log('Doing something with ' + list[itemIndex]);
};
};for (i = 0; i < list.length; i += 1) {
list[i].onclick = doSomethingHandler(i);}
了解更多关于 闭包及其用法的信息 。
函数表达式可以直接传递给函数,而不必分配给中间临时变量。
您最常以匿名函数的形式看到它们。 这是一个熟悉的 jQuery 函数表达式示例:
$(document).ready(function () {
console.log('An anonymous function');});
在使用诸如
forEach()
.
它们也不必是未命名的匿名函数。 命名函数表达式以帮助表达函数应该做什么并帮助调试是一个好主意:
let productIds = ['12356', '13771', '15492'];productIds.forEach(function showProduct(productId) {
...});
IIFE 有助于防止您的函数和变量影响全局范围。
其中的所有属性都在匿名函数的范围内。 这是一种常见的设计模式,用于防止您的代码在其他地方产生不希望的或不希望的副作用。
它还用作模块模式,在易于维护的部分中包含代码块。 我们将在 Demystifying JavaScript 闭包、回调和 IIFE 中深入了解这些内容。
下面是一个 IIFE 的简单示例:
(function () {
// code in here}());
…当用作模块时,可以为您的代码带来一些易于实现的可维护性。
let myModule = (function () {
let privateMethod = function () {
console.log('A private method');
},
someMethod = function () {
console.log('A public method');
},
anotherMethod = function () {
console.log('Another public method');
};
return {
someMethod: someMethod,
anotherMethod: anotherMethod
};}());
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70015022/viewspace-2884809/ ,如需转载,请注明出处,否则将追究法律责任。