JavaScript函数是一等公民,可赋值、传参、返回;function声明全提升,表达式仅变量名提升;箭头函数无this/arguments;参数不校验个数,支持默认值和剩余参数;IIFE用于作用域隔离,call/apply/bind控制this绑定。

JavaScript 函数是可复用的代码块,用来执行特定任务或计算并返回结果
它不是对象、类或语法糖,而是一等公民(first-class citizen):可以赋值给变量、作为参数传入其他函数、从函数中返回。定义后不自动运行,必须显式调用。
function 声明 vs function 表达式:两种最常用定义方式
区别不在功能,而在**提升(hoisting)行为**和**命名可见性**上,直接影响调用时机和调试体验:
-
function声明会被完全提升,可在定义前调用;const myFn = function() {}这类表达式只提升变量名(myFn),不提升函数体,提前调用会报TypeError: myFn is not a function - 表达式中的函数若无名字(即匿名),在堆栈跟踪里显示为
anonymous;加上名字如const myFn = function namedFn() {},既利于调试,又能让函数内部递归调用自己(namedFn()) - 箭头函数
const myFn = () => {}不能用作构造函数,且没有自己的this、arguments、new.target
调用函数时传参和接收参数的常见误区
JS 不检查实参个数是否匹配形参,多传或少传都不会报错,但语义可能出问题:
- 少传参数 → 对应形参值为
undefined;可用默认参数规避:function greet(name = 'Guest') { ... } - 多传参数 → 多余参数可通过
arguments类数组访问(仅普通函数),或用剩余参数function(...args) { } - 传对象或数组时,函数内修改其属性/元素会影响原值(引用传递),但重新赋值给参数变量不会(如
obj = {}只改本地绑定)
立即执行函数表达式(IIFE)和 call/apply/bind 的典型用途
它们解决的是「执行上下文控制」和「环境隔离」问题,不是炫技:
立即学习“Java免费学习笔记(深入)”;
- IIFE(如
(function(){...})())常用于避免污染全局作用域,或创建私有变量(闭包);ES6 后更多用模块封装替代 -
call和apply立即调用并指定this,区别只在参数传法:fn.call(obj, a, b)vsfn.apply(obj, [a, b]) -
bind返回新函数,this和部分参数被固化,适合事件回调、防抖节流等需预设上下文的场景
const user = { name: 'Alice' };
function introduce(greeting, punctuation) {
return `${greeting}, I'm ${this.name}${punctuation}`;
}
introduce.call(user, 'Hi', '!'); // "Hi, I'm Alice!"
const boundIntro = introduce.bind(user, 'Hello');
boundIntro('.'); // "Hello, I'm Alice."
函数的“复杂点”往往不在定义语法,而在调用时的 this 绑定、参数传递的隐式转换、以及闭包中对外部变量的捕获时机——这些地方稍不注意,就会出现值不对、this 指向丢失、内存泄漏等问题。











