JavaScript基础篇——第四章 函数与作用域

目录

十、函数与作用域

10.1 函数本质与声明

10.2 函数命名规范

10.3 函数调用机制

10.4 函数参数详解

10.4.1 参数传递原理

10.4.2 默认参数值

10.5 返回值核心机制

10.5.1 return 关键字

10.5.2 返回值应用场景

10.6 参数与返回值实战案例

10.7 易错点与调试技巧

10.8 作用域深度解析

10.8.1 作用域层级

10.8.2 作用域链机制

10.8.3 变量类型与规范

10.9 函数高级形态

10.9.1 具名函数

10.9.2 匿名函数

10.9.3 立即执行函数(IIFE)

10.10 逻辑运算符短路规则

10.10.1 短路本质

10.10.2 短路应用

10.11 类型转换机制

10.11.1 隐式转换规则

10.11.2 转换陷阱案例


这篇文章系统地介绍了JavaScript函数与作用域的核心概念,主要内容包括:1. 函数本质与声明方式(封装代码块、洗衣机类比);2. 函数命名规范(小驼峰、动词前缀);3. 参数传递机制(形参/实参、默认值);4. 返回值原理(return双重作用);5. 作用域规则(全局/局部/嵌套、作用域链);6. 函数高级形态(具名/匿名/IIFE);7. 逻辑运算符短路规则;8. 类型转换机制与陷阱。文章强调函数作为独立执行单元的特性,并通过大量代码示例和类比说明关键概念,同时指出常见错误和调试技巧。

十、函数与作用域

10.1 函数本质与声明

核心定义:

封装可重复执行代码块的逻辑单元

类比:洗衣机(输入脏衣服+参数 → 执行清洗程序 → 返回干净衣服+返回值)

声明语法:

function 动词名() {  // ⚠️ 必须使用 function 关键字

    // 函数体(被"包裹"的代码)

}

执行特性:

1.函数体代码在调用前不会执行(类似洗衣机待启动)

2.调用后创建独立执行上下文(内部变量与外部隔离)

10.2 函数命名规范

规则类型

要求

示例

错误案例

格式规则

小驼峰命名法

calculateTotal()

Calculate_total()

前缀规范

动词开头

getUserData()

userDataFetch()

语义约定

常用动词表(强化可读性)

常用动词前缀表:

动词

含义

应用场景

can

判断可行性

canEditContent()

has

判断包含关系

hasPermission()

is

判断状态

isValidEmail()

get

获取数据

getCurrentTime()

set

设置值

setFontSize()

load

加载资源

loadImage()

handle

处理事件

handleClick()

10.3 函数调用机制

调用语法:函数名() ⚠️ 必须有括号

执行原理:

关键特性:

1.单次声明可无限次调用

2.每次调用创建新的执行上下文

3.与循环的区别:

特性

函数

循环

执行控制

按需调用

立即执行

作用域

独立上下文(变量隔离)

共享外部作用域

10.4 函数参数详解


10.4.1 参数传递原理

形参(Formal Parameter):

function getSum(num1, num2) { // num1/num2是形参

    return num1 + num2;

}

实参(Actual Parameter):

getSum(10, 20); // 10和20是实参

内存映射关系:


调用时:实参 → 赋值给 → 形参变量

       [10]    →    num1

       [20]    →    num2

10.4.2 默认参数值

问题场景:

getSum(); // num1=undefined, num2=undefined → NaN

解决方案:

function getSum(num1 = 0, num2 = 0) {

    return num1 + num2;

}

执行规则:

1.有实参 → 使用实参值

2.无实参 → 使用默认值

3.部分实参 → 剩余参数用默认值

10.5 返回值核心机制


10.5.1 return 关键字

双重作用:

1.返回数据给调用者

2.立即终止函数执行(后续代码不运行)

function checkAge(age) {

    if (age < 18) return "未成年"; // 此处终止

    console.log("此代码不会执行");

    return "成年人";

}

返回规则:

返回形式

结果

return 值;

返回指定值

return;

返回 undefined

无 return

返回 undefined

10.5.2 返回值应用场景

// 场景1:直接使用返回值

let total = calculatePrice(100, 3); // 300



// 场景2:链式调用

getUserData().filter().map();



// 场景3:条件判断

if (isValid(input)) {

    // 执行操作

}

10.6 参数与返回值实战案例

// 商品折扣计算函数

function applyDiscount(price, discount = 0.1) {

    // 输入验证

    if (typeof price !== 'number' || price <= 0) {

        return "价格无效"; // 提前终止

    }

   

    // 计算折扣价

    const finalPrice = price * (1 - discount);

   

    // 返回结果对象

    return {

        original: price,

        discountRate: discount,

        final: finalPrice.toFixed(2)

    };

}



// 调用示例

const result = applyDiscount(200, 0.2);

console.log(result);

/* 输出:

{

  original: 200,

  discountRate: 0.2,

  final: "160.00"

} */

10.7 易错点与调试技巧

错误类型

案例

解决方案

忘记调用括号

sayHi; (未执行)

sayHi();

参数个数不符

getSum(10) (缺参数)

使用默认参数值

return 后换行

return\n x+y; → 返回undefined

确保return与值在同一行

作用域混淆

函数内访问外部未声明变量

使用参数传递数据

调试工具使用:

1.在函数体内设置断点(Sources面板)

2.监控形参值(Watch窗口添加变量)

3.跟踪返回值(Console输出或Watch监控)

10.8 作用域深度解析


10.8.1 作用域层级

全局作用域:

1.生效范围:整个 <script> 标签或独立 JS 文件

2.生命周期:随页面加载创建,页面关闭销毁

局部作用域:

1.生效范围:函数内部(又称函数作用域)

2.生命周期:函数调用时创建,执行完毕销毁

嵌套作用域:

function outer() {

    // 外层局部作用域

    let a = 10;

   

    function inner() {

        // 内层局部作用域

        console.log(a); // 访问外层变量

    }

    inner();

}

10.8.2 作用域链机制

访问原则:

"就近优先,逐级向上"

经典案例:

let globalVar = "全局";



function outer() {

    let outerVar = "外层";

    

    function inner() {

        let innerVar = "内层";

        console.log(innerVar); // "内层"(当前作用域)

        console.log(outerVar); // "外层"(父作用域)

        console.log(globalVar); // "全局"(全局作用域)

    }

    inner();

}

outer();

10.8.3 变量类型与规范

变量类型

声明位置

访问范围

生命周期

是否推荐

全局变量

函数外部

任何位置

页面打开到关闭

谨慎使用

局部变量

函数内部

当前函数内部

函数执行期间

推荐

隐式全局

未声明直接赋值

全局

同全局变量

❌ 禁止

特殊注意:

function dangerous() {

    // 未使用let声明 → 成为隐式全局变量!

    leakVar = "污染全局";

}

dangerous();

console.log(leakVar); // "污染全局"(应报错但实际可访问)

10.9 函数高级形态


10.9.1 具名函数

标准声明:

// 声明与调用分离

function calculate() { ... }

calculate();

核心特性:

函数提升(可在声明前调用)

sayHello(); // 正常执行(提升机制)

function sayHello() { console.log("Hi"); }

10.9.2 匿名函数

函数表达式:

// 匿名函数赋值给变量

const greet = function() {

    console.log("你好!");

};

greet(); // 调用

特性对比具名函数:

特性

具名函数

匿名函数表达式

提升

✅ 可先调用后声明

❌ 必须先赋值后调用

调试

显示函数名

显示变量名或anonymous

递归调用

可直接用函数名

需通过变量名

10.9.3 立即执行函数(IIFE)

语法结构:

// 标准形式

(function() {

    console.log("立即执行");

})();



// 带参数版本

(function(name) {

    console.log(`Hello ${name}`);

})("张三");

核心价值:

避免污染全局:

// 全局变量

let count = 0;



(function() {

    // 局部变量,不污染全局

    let privateCount = 10;

})();

封装私有数据:

const counter = (function() {

    let count = 0; // 私有变量

   

    return {

        increment: function() { count++; },

        get: function() { return count; }

    };

})();



counter.increment();

console.log(counter.get()); // 1

console.log(count); // 报错!count未定义

分号警示:

// 错误!前一行缺少分号导致解析失败

let x = 10

(function() { ... })()



// 正确:前一行加分号

let x = 10;

(function() { ... })()

10.10 逻辑运算符短路规则


10.10.1 短路本质

触发条件:

运算符

短路条件

执行规则

&&

左侧为假值

右侧不执行

`

`

左侧为真值

右侧不执行

假值列表:false, 0, "", null, undefined, NaN

10.10.2 短路应用

条件执行:


// 用户存在时执行操作

user && user.save();



// 等同于

if (user) user.save();

默认值设置:


// 若name为假值,使用"匿名"

const displayName = name || "匿名";

安全访问:

// 避免访问undefined属性

const street = user && user.address && user.address.street;

10.11 类型转换机制


10.11.1 隐式转换规则

操作类型

转换规则

示例

结果

字符串加法

任何类型 → 字符串

"" + 1

"1"

数学运算

字符串 → 数字(失败为NaN)

"10" - 5

5

"pink" - 1

NaN

null转换

数学运算中 → 0

null + 1

1

undefined转换

数学运算中 → NaN

undefined + 1

NaN

布尔转换

逻辑判断中自动转换

if("hello") {...}

执行代码

10.11.2 转换陷阱案例

console.log('' - 1);        // -1 (空字符串→0)

console.log('pink' - 1);    // NaN (非数字字符串)

console.log(null + 1);      // 1 (null→0)

console.log(undefined + 1); // NaN (undefined→NaN)

console.log(NaN + 1);       // NaN (任何数+NaN=NaN)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值