JavaScript 函数完整入门指南:声明、调用、参数、返回值、作用域全解析
前言
函数是 JavaScript 的核心基石,也是代码复用、逻辑封装的核心手段。很多前端初学者刚接触 JS 时,分不清函数声明 / 函数表达式、形参与实参、局部 / 全局作用域,写代码时经常出现变量冲突、调用报错、返回值丢失等问题。
本文结合经典《JavaScript & jQuery 交互式 Web 前端开发》教材案例,从零拆解 JS 函数全套知识点,包含可运行示例、核心概念对比、实战使用场景,看完彻底吃透基础函数,适配新手入门与面试复习。
一、什么是函数?基础示例看懂函数作用
函数本质是封装一组可重复执行代码的代码块,把完成特定任务的语句打包,需要时直接调用,避免重复抄写代码。
实战完整案例(页面修改 DOM 文本)
HTML 代码(basic-function.html)
html
预览
<!DOCTYPE html> <html> <head> <title>Basic Function</title> <link rel="stylesheet" href="css/c03.css" /> </head> <body> <h1>TravelWorthy</h1> <div id="message">Welcome to our site!</div> <!-- 引入外部JS文件 --> <script src="js/basic-function.js"></script> </body> </html>JS 代码(basic-function.js)
javascript
运行
// 全局消息变量 var msg = 'Sign up to receive our newsletter for 10% off!'; // 函数声明:封装修改页面文本逻辑 function updateMessage() { // 获取id为message的DOM元素 var el = document.getElementById('message'); // 修改元素文本内容 el.textContent = msg; } // 调用函数,执行内部代码 updateMessage();运行结果说明
页面原本显示Welcome to our site!,JS 文件加载后调用updateMessage()函数,自动替换 div 内文本为优惠提示文案。
- 函数内代码只有调用时才会执行,不调用则内部逻辑永远不会运行;
- 同一函数可在代码任意位置多次调用,复用 DOM 修改逻辑。
二、函数的两种基础操作:声明函数 + 调用函数
2.1 function 关键字声明函数(命名函数)
语法规则:function 函数名() { 代码块 }拆解语法组成:
function:JS 内置关键字,代表声明函数;- 函数名:自定义标识符,用于后续调用;
():括号,可存放参数,无参数留空;{}:函数体,存放需要执行的所有业务代码。
示例:无参基础函数
javascript
运行
// 函数声明 function sayHello() { document.write('Hello!'); }2.2 调用函数:执行函数内部代码
声明函数后,函数不会自动执行,必须通过函数名()格式调用:
javascript
运行
// 调用函数,执行{}内所有代码 sayHello();调用特性:
- 同一个函数可调用无数次,每次调用都会重新执行内部代码;
- JS 存在函数提升:function 声明的函数,可以写在调用语句之后,解释器会提前扫描全局函数定义,不会报错。
示例(调用写在函数声明前,合法):
javascript
运行
sayHello(); function sayHello() { document.write('Hello!'); }三、带参数的函数:形参、实参完整区分
很多场景下函数执行需要外部传入数据(比如计算面积需要长宽),此时就要用到参数,分为形参和实参两个核心概念。
3.1 形参:函数声明时定义的占位变量
写在函数括号内的变量名就是形参,仅在函数内部生效,行为等同于局部变量。
javascript
运行
// width、height 是形参 function getArea(width, height) { return width * height; }3.2 实参:调用函数时传入的真实数据
调用函数括号内传递的真实值 / 变量,叫做实参,会一一对应赋值给形参。 两种传参方式:
- 直接传入字面量数值
javascript
运行
// 3对应width,5对应height,3、5是实参 getArea(3, 5);- 传入已定义变量
javascript
运行
var wallWidth = 3; var wallHeight = 5; // 变量作为实参传递 getArea(wallWidth, wallHeight);3.3 形参 VS 实参核心区别对照表
表格
| 维度 | 形参 | 实参 |
|---|---|---|
| 出现位置 | 函数声明function fn(形参1,形参2) | 函数调用fn(实参1,实参2) |
| 本质 | 函数内部的占位变量 | 真实的数据 / 变量 |
| 作用域 | 仅函数内部可用 | 全局 / 当前作用域任意数据 |
四、函数返回值:return 获取函数执行结果
函数执行计算、处理逻辑后,经常需要把结果交给外部代码使用,依靠return关键字实现返回值。
4.1 返回单个数值
语法:return 数据;,执行 return 后函数会立刻终止,return 后的代码不会运行。
javascript
运行
function calculateArea(width, height) { var area = width * height; // 返回计算结果 return area; // 下面代码永远不会执行 console.log('这段代码不会运行'); } // 接收函数返回值,存入变量 var wallOne = calculateArea(3, 5); // wallOne = 15 var wallTwo = calculateArea(8, 5); // wallTwo = 404.2 返回多个值(借助数组)
JS 中return只能返回一个数据,如需同时返回多个结果,可将数据存入数组 / 对象后统一返回:
javascript
运行
// 计算矩形面积+立方体体积,返回两个结果 function getSize(width, height, depth) { var area = width * height; var volume = width * height * depth; // 数组打包多个值返回 var sizes = [area, volume]; return sizes; } // 通过数组下标分别取出返回值 var areaOne = getSize(3, 2, 3)[0]; // 面积 6 var volumeOne = getSize(3, 2, 3)[1]; // 体积 18五、两种函数定义方式:函数声明 VS 函数表达式
JS 定义函数分为两大体系:function函数声明、函数表达式(匿名函数),二者核心区别是函数提升。
5.1 函数声明(前文已用)
javascript
运行
function area(width, height) { return width * height; } // 可在声明前调用,存在提升 var size = area(3, 4);5.2 函数表达式(匿名函数)
将匿名函数赋值给变量,变量名作为调用标识,不存在提升,必须先定义再调用。
javascript
运行
// 匿名函数赋值给变量area var area = function(width, height) { return width * height; }; // 必须写在表达式定义之后,写前面会报错 var size = area(3, 4);核心差异总结
- 函数声明:有函数名、存在提升、可先调用后定义;
- 函数表达式:大多为匿名函数、无提升、必须先定义后调用;
- 适用场景:封装通用逻辑用函数声明;回调、事件、一次性逻辑用函数表达式。
六、IIFE 立即调用函数表达式(匿名函数一次性执行)
IIFE 全称 Immediately Invoked Function Expression,读作 “iffy”,是函数表达式的特殊用法:定义完成立刻执行,仅运行一次。
标准 IIFE 写法
javascript
运行
var area = (function() { var width = 3; var height = 2; // 函数执行完直接返回结果,存入area变量 return width * height; })(); console.log(area); // 6语法拆解:
(function(){}):括号将匿名函数转为表达式;- 末尾
():代表立刻执行这个函数;
IIFE 核心使用场景
- 仅需运行一次的初始化代码;
- 隔离变量,避免全局命名冲突(配合作用域);
- 事件回调、函数传参、第三方库封装(jQuery 底层大量使用)。
七、变量作用域:局部变量 & 全局变量(避坑重点)
函数内部 / 外部定义的变量,访问范围完全不同,这个访问范围叫做作用域,也是新手最容易踩坑的知识点。
7.1 局部变量(函数作用域)
在函数内部使用var声明的变量,仅当前函数内部能访问,函数执行完毕后变量销毁,不占用长期内存。
javascript
运行
function getArea(width, height) { // area是局部变量,函数外无法访问 var area = width * height; return area; } console.log(area); // 报错:area未定义局部变量优势:
- 不同函数可使用同名变量,不会冲突;
- 函数执行完自动销毁,节省浏览器内存。
7.2 全局变量
函数外部、script 顶层定义的变量,整个页面所有 JS 代码、所有函数都能访问,生命周期和页面一致,页面关闭才销毁。
javascript
运行
// wallSize是全局变量 var wallSize = 10; function getArea() { // 函数内可直接读取全局变量 console.log(wallSize); }全局变量缺点:
- 长期驻留内存,页面加载全程占用资源;
- 多 JS 文件协同开发时,极易出现命名冲突;
- 代码耦合度高,维护困难。
补充:不写 var 的隐形全局变量
函数内部定义变量时,省略var关键字,变量会自动变成全局变量,属于不良编码习惯,开发中禁止使用:
javascript
运行
function test() { // 无var,width自动升级为全局变量 width = 10; } test(); console.log(width); // 10,外部可访问作用域内存原理
- 全局变量:页面载入时创建,页面关闭才销毁,长期占用内存;
- 局部变量:函数调用时创建,函数执行结束立刻销毁,内存开销更小;
- 开发规范:优先使用局部变量,尽量少定义全局变量。
八、完整知识点思维导图(复习速记)
plaintext
JS函数 ├─ 定义方式 │ ├─ 函数声明 function fn(){} 【有提升,可先调用】 │ └─ 函数表达式 var fn = function(){} 【无提升,匿名】 │ └─ IIFE 立即执行函数 (function(){})() 一次性执行、隔离变量 ├─ 参数体系 │ ├─ 形参:声明时括号内占位变量 │ └─ 实参:调用时传入真实数据/变量 ├─ 返回值 return │ ├─ 返回单个数据 return 123; │ └─ 返回多个数据 return [a,b];(数组承载) ├─ 调用规则 fn() │ └─ 不写()仅代表函数本身,加()才会执行 └─ 变量作用域 ├─ 局部变量:函数内var定义,仅内部访问,执行后销毁 └─ 全局变量:顶层定义,全页面访问,长期占用内存九、新手高频踩坑总结
- 函数表达式写在调用之后,报
is not a function错误; 解决:函数表达式必须先定义,再调用;function 声明无限制。 - return 后仍写代码,逻辑不执行; 解决:return 会终止函数,后续代码全部失效。
- 函数内变量外部读取不到; 解决:函数内 var 变量是局部变量,外部无法访问,需要 return 导出。
- 多文件变量重名,值被莫名覆盖; 解决:减少全局变量,使用 IIFE、局部变量隔离命名空间。
- 省略 var 定义变量,意外污染全局; 解决:所有变量声明强制添加 var/let/const。
结语
函数是 JS 模块化、代码复用的根基,本文覆盖教材全部核心案例,从基础定义到作用域、IIFE 完整覆盖。掌握本文内容后,可以轻松看懂回调函数、对象方法、闭包等进阶知识点,后续会持续更新 JS 函数进阶(闭包、箭头函数、this 指向)系列文章。
