# JavaScript 基础 - 第 4 天笔记

理解封装的意义,能够通过函数的声明实现逻辑的封装,知道对象数据类型的特征,结合数学对象实现简单计算功能。

  • 理解函数的封装的特征
  • 掌握函数声明的语法
  • 理解什么是函数的返回值

# 1. 函数

理解函数的封装特性,掌握函数的语法规则

# 1.1 为什么学习函数?

函数:就是 <span style="color:red;"> 封装重复执行的代码块 </span>。

# 1.2 函数的使用

函数使用分成两步:

  • <span style="color:red;"> 声明函数 </span>
  • 调用函数

# 1.2.1 声明函数

1
2
3
4
5
// 语法规范
// 声明函数
function 函数名() {
//函数体代码
}

  • <span style="color: red;">function</span> 是声明函数的关键字,<span style="color: red;"> 必须小写 </span>

  • 由于函数一般是 <span style="color: red;"> 为了实现某个功能 </span> 才定义的, 所以通常我们对 <span style="color:red;"> 函数名 </span> 命名为 < span style="color:red;"> 动词 </span>,比如 getSum(求和函数)

# 1.2.2 调用函数

1
2
// 调用函数
函数名(); // 通过调用函数名来执行函数体代码

  • 调用的时候千万 <span style="color:red;"> 不要忘记添加小括号 </span>

  • 口诀:函数不调用,自己不执行

  • 注意:<span style="color: red;"> 声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码 </span>

# 2.2.3 函数的封装

  • 函数的封装是 <span style="color:red;"> 把一个或者多个功能通过函数的方式封 </span> 装起来,对外只提供一个简单的函数接口

  • 简单理解:封装类似于将电脑配件整合组装到机箱中。

# 2.2.4 封装计算 1-100 累加和

1
2
3
4
5
6
7
8
9
10
11
// 计算1-100之间值的函数
// 声明函数
function getSum(){
var sumNum = 0;// 准备一个变量,保存数字和
for (let i = 1; i <= 100; i++) {
sumNum += i;// 把每个数值 都累加 到变量中
}
alert(sumNum);
}
// 调用函数
getSum();

# 2.2.5 函数使用部分的提问

  • 函数是做什么的(作用)?函数就是封装了一段可重复执行的代码,通过函数可以提高代码的利用率。

  • 声明函数用什么关键词? function

  • 如何调用函数? 函数名 ()

  • 封装是什么意思?就是把一个或者多个功能组合在一个函数里

# 1.3 函数的参数

函数传参

<span style="color:red;"> 在声明函数时 </span>,可以在函数名称后面的 < span style="color:red;"> 小括号中添加一些参数 </span>,这些参数被称为 < span style="color:red;"> 形参 (形式上的参数)</span>,

<span style="color:red;"> 在调用该函数 </span> 时,同样也需要传递相应的参数,这些参数被称为 < span style="color:red;"> 实参 </span>。

  • 形参:<span style="color: red;"> 函数定义时设置接收调用时传入的实际参数值的类似于一个变量 </span>

  • 实参:<span style="color:red;"> 函数调用时传入小括号内的真实数据 </span>

    <span style="color:red;"> 参数的作用 </span>: 在函数内部某些值不能固定,我们可以通过参数在调用函数时传递不同的值进去。

    函数参数的运用:

    1
    2
    3
    4
    5
    6
    // 带参数的函数声明
    function 函数名(形参1, 形参2 , 形参3...) { // 可以定义任意多的参数,用逗号分隔
    // 函数体
    }
    // 带参数的函数调用
    函数名(实参1, 实参2, 实参3...);

    1. 调用的时候实参值是传递给形参的
    2. 形参简单理解为:不用声明的变量
    3. 实参和形参的多个参数之间用逗号(,)分隔

案例

1
2
3
// 1. 利用函数求两个数的和

// 2. 利用函数求1-100的累加和

# 1.3.1 函数默认参数

形参: 可以看做变量,但是如果一个变量不给值,默认是什么?

答:undefined

但是如果做用户不输入实参,刚才的案例,则出现 undefined + undefined 结果是什么?

答:NaN

我们可以改进下,用户不输入实参,可以给 形参默认值,可以默认为 0, 这样程序更严谨,可以如下操作:

1
2
3
4
5
6
7
function getSum(x = 0, y = 0) {
// x = 1
// num1 默认的值 undefined
document.write(x + y)
}
getSum(1, 2)
getSum() // 0

注意:

这个默认值只会在缺少实参参数传递时,才会被执行,所以有实参的时候会优先执行传递过来的实参

# 1.3.2 实参可以是变量

1
2
3
4
let num1 = +prompt('请输入起始值:')
let num2 = +prompt('请输入结束值:')
// 调用函数
getSum(num1, num2) // 实参可以是变量

# 1.3.3 函数形参和实参数量不匹配时

注意:在JavaScript中,形参的默认值是undefined。

小结:

  • 函数可以带参数也可以不带参数
  • 声明函数的时候,函数名括号里面的是形参,形参的默认值为 undefined
  • 调用函数的时候,函数名括号里面的是实参
  • 多个参数中间用逗号分隔
  • 形参的个数可以和实参个数不匹配,但是结果不可预计,我们尽量要匹配

# 1.4 函数的返回值

提问:什么是函数?

答:函数是被设计为执行特定任务的代码块

提问:执行完特定任务之后,然后呢?

答: 把任务的结果给我们

  • 返回值:函数调用整体代表的数据;函数执行完成后可以通过 return 语句将指定数据返回 。
  • 缺点:把计算后的结果处理方式写死了,内部处理了
    解决:把处理结果返回给调用者
# 1.4.1 return 关键字

当函数需要返回数据出去时,用 return 关键字

1
2
3
4
5
6
7
8
2. 函数的返回值格式
function 函数名() {
return 需要返回的结果;
}
函数名();

(1) 我们函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名() 通过return 实现的
(2) 只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果

总结:

  1. 在函数体中使用 return 关键字能将内部的执行结果交给函数外部使用
  2. 函数内部只能出现 1 次 return,并且 return 下一行代码不会再被执行
  3. return 会立即结束当前函数,并返回指定的值
  4. 函数可以没有 return,这种情况默认返回值为 undefined

# 1.5 作用域

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。

# 1.5.1 全局作用域

作用于所有代码执行的环境 (整个 script 标签内部) 或者一个独立的 js 文件

处于全局作用域内的变量,称为全局变量

# 1.5.2 局部作用域

作用于函数内的代码环境,就是局部作用域。 因为跟函数有关系,所以也称为函数作用域。

处于局部作用域内的变量称为局部变量

# 1.5.3 变量的特殊情况

  1. 在函数内部不声明 直接赋值(强烈不推荐)
  2. 形参可以看做是函数的局部变量
  3. 作用域链:内部函数访问变量,先在自身作用域找声明,如果没有,往外层找,直到找到全局,如果有,采取就近原则
# 提问

1
2
3
4
5
6
7
8
9
function f1() {
let num = 123
function f2() {
console.log( num )
}
f2()
}
let num = 456
f1()

# 1.6 匿名函数

函数可以分为具名函数 (命名函数) 和匿名函数

匿名函数:没有名字的函数,无法直接使用。

  • # 函数表达式

1
2
3
4
5
6
// 声明
let fn = function() {
console.log('函数表达式')
}
// 调用
fn()

  • # 立即执行函数

1
2
(function(){ xxx  })();
(function(){xxxx}());

注意:

无需调用,立即执行,其实本质已经调用了

多个立即执行函数之间用分号隔开

总结

1. 立即执行函数有什么作用?

  • 防止变量污染

2. 立即执行函数需要调用吗? 有什么注意事项呢?

  • 无需调用,立即执行,其实本质已经调用了
  • 多个立即执行函数之间用分号隔开

# 2. 短路运算(逻辑中断)

  • 逻辑与只要碰到了假值 (false),就会短路,并返回该假值, 只要短路,不会继续执行后面的表达式。

    语法: 表达式 1 && 表达式 2

    如果第一个表达式的值为真,则返回表达式 2

    如果第一个表达式的值为假,则返回表达式 1

    1
    2
    3
    console.log( 123 && 456 );        // 456
    console.log( 0 && 456 ); // 0
    console.log( 123 && 456&& 789 ); // 789

  • 逻辑或 (只要碰到了真值 (true),就会短路,并返回该真值, 只要短路,不会继续执行后面的表达式。(一般用作默认值))

    语法: 表达式 1 || 表达式 2

    如果第一个表达式的值为真,则返回表达式 1

    如果第一个表达式的值为假,则返回表达式 2

    1
    2
    3
    console.log( 123 || 456 );         //  123
    console.log( 0 || 456 ); // 456
    console.log( 123 || 456 || 789 ); // 123

注意

如果有空的或者否定 <span style="color:red;">( 0 ' ' null undefined NaN)</span > 的为假

其余是真的

# 3. 转换为布尔型

  • 代表空、否定的值会被转换为 false ,如 ''、0、NaN、null、undefined

  • 其余值都会被转换为 true

    1
    2
    3
    4
    5
    6
    7
    console.log(Boolean('')); // false
    console.log(Boolean(0)); // false
    console.log(Boolean(NaN)); // false
    console.log(Boolean(null)); // false
    console.log(Boolean(undefined)); // false
    console.log(Boolean('小白')); // true
    console.log(Boolean(12)); // true

​ 在能够访问到的情况下 先局部 局部没有在找全局