JavaScript 函数详解

本文深入探讨JavaScript中的函数,包括函数定义(声明、表达式、Function构造函数、箭头函数),函数名称的特点,参数的处理(Arguments对象、默认参数、剩余参数),函数调用的[[Call]]和[[Construct]]内部方法,函数递归,以及箭头函数的语法和this行为。此外,还介绍了立即调用函数表达式(IIFE)的概念。
摘要由CSDN通过智能技术生成

前言:JavaScript 中的函数是什么

一般来说,一个函数是可以通过外部代码调用的一个“子程序”。像程序本身一样,一个函数由称为函数体的一系列语句组成。值可以传递给一个函数,函数将返回一个值。
但在 JavaScript 中比较特殊的是,函数实际上也是一个对象。每个函数都是Function 类型的实例,所以和其他对象一样具有属性和方法,区别在于函数可以被调用。

一、函数定义

定义函数有多种方法,主要分为函数声明和函数表达式。

1.1 函数声明

function Identifier ( FormalParameterList ) { FunctionBody } 
  • Identifier:函数标识符(函数名)
  • FormalParameterList:参数列表
  • FunctionBody:函数体

1.2 函数表达式

(1)具名函数表达式

const myFunction = function Identifier ( FormalParameterList ) { FunctionBody } 

(2)匿名函数表达式

const myFunction = function ( FormalParameterList ) { FunctionBody } 

1.3 Function 构造函数

new Function (arg1, arg2, ... argN, functionBody) 
  • arg1, arg2, ... argN:函数使用零个或多个名称作为正式的参数名称。每一个必须是一个符合有效的JavaScript标识符规则的字符串或用逗号分隔的字符串列表
  • functionBody:一个构成的函数定义的,包含JavaScript声明语句的字符串。

注意:MDN官方不推荐使用Function构造函数创建函数,因为可能会影响JavaScript引擎优化。

1.4 箭头函数表达式

([param] [, param]) => { statements } 

param => expression 
  • param:参数名称. 零参数需要用()表示.  只有一个参数时不需要括号. (例如 foo => 1)
  • statements or expression:多个声明statements需要用大括号括起来,而单个表达式时则不需要。表达式expression也是该函数的隐式返回值。

有关箭头函数后文详细介绍。

函数声明、函数表达式、Function构造函数的区别

假设我们要定义一个函数multiply计算两个数的乘积,那么通过不同的方法定义如下:

// 函数声明
function multiplyDeclaration(x, y) {
    return x * y;
}  // 注意:函数声明结尾一般没有分号

// 匿名函数表达式
const multiplyAnonymousExpression = function (x, y) {
    return x * y;
};

// 具名函数表达式
const multiplyNamedExpression = function funcName(x, y) {
    return x * y;
};

// Function 构造函数
const multiplyFunctionConstructor = new Function('x', 'y', 'return x * y'); 

(1)函数声明提升

JavaScript引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。而函数表达式必须等到代码执行到它那一行时,才会在执行上下文中生成函数定义。

console.log(multiplyDeclaration(3, 7));  // 21
console.log(multiplyAnonymousExpression(3, 7)); // ReferenceError: Cannot access 'multiplyAnonymousExpression' before initialization

// 函数声明
function multiplyDeclaration(x, y) {
    return x * y;
}  // 注意:函数声明结尾一般没有分号

// 匿名函数表达式
const multiplyAnonymousExpression = function (x, y) {
    return x * y;
}; 

可以看出,在函数声明之前调用该函数并不会出错,但是函数表达式会出现ReferenceError。

函数声明和函数表达式最大的区别在于:函数声明会提升

(2)性能问题

通过函数表达式定义的函数和通过函数声明定义的函数只会被解析一次,而Function构造函数定义的函数却不同。每次构造函数被调用,传递给Function构造函数的函数体字符串都要被解析一次 。 所以Function构造函数应尽可能地避免使用。

二、函数名称

函数名是指向函数的指针,可以通过 function.name 属性访问函数实例的名称。若函数没有名称,则会返回一个空字符串。 函数名称是不可写、不可迭代、可配置的属性,即{writable: false, enumerable: false, configurable: true}

(1)函数声明的名称

name 属性返回一个函数声明的名称。

function foo() {

}
console.log(foo.name); 

(2)通过new Function() 创建的函数

使用new Function(...)语法创建的函数,其名称为“anonymous”。

(new Function).name; // "anonymous&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值