一、函数的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
函数的定义方式:
1.函数声明
function 函数名([参数]){
语句...
}

2.函数表达式
const 变量 = function([参数]){
语句...
}

3.箭头函数 //当箭头函数只有一个参数时,可以省略括号
([参数]) => {
语句...
}

二、函数的参数

  • 形式参数
    在定义函数时,可以在函数中指定数量不等的形式参数(形参)
    在函数中定义形参,就相当于在函数内部声明了对应的变量但是没有赋值
  • 实际参数
    在调用函数时,可以在函数的()传递数量不等的实参
    实参会赋值给其对应的形参
  • 参数:
    1.如果实参和形参数量相同,则对应的实参赋值给对应的形参
    2.如果实参多余形参,则多余的实参不会使用
    3.如果形参多余实参,则多余的形参为undefined
  • 参数的类型:JS中不会检查参数的类型,可以传递任何类型的值作为参数

1、对象作为参数

1
2
3
4
5
6
function fn(a){
a.name = "张三"
console.log(a)
}
let obj = {name:"李四"}
fn(obj)

2、函数作为参数

1
2
3
4
5
6
7
function fn(a){
console.log("a =", a)
}
function fn2(){
console.log("我是fn2")
}
fn(fn2)

三、函数的返回值

  • 在函数中,可以通过return关键字来指定函数的返回值
    ​ 返回值就是函数的执行结果,函数调用完毕返回值便会作为结果返回
  • 任何值都可以作为返回值使用(包括对象和函数之类)
    ​ 如果return后不跟任何值,则相当于返回undefined
    ​ 如果不写return,那么函数的返回值依然是undefined
  • return一执行函数立即结束,后面的语句不再执行

补充:箭头函数的返回值

1
2
3
4
5
6
7
8
 //箭头函数的返回值可以直接写在箭头后
//如果直接在箭头后设置对象字面量为返回值时,对象字面量必须使用()括起来
const sum = (a, b) => a + b
const fn = () => ({name:"孙悟空"})

let result = sum(123, 456)
result = fn()
console.log(result)

四、作用域

作用域指的是一个变量的可见区域,包括全局作用域与局部作用域

  • 全局作用域
    全局作用域在网页运行时创建,在网页关闭时消耗
    所有直接编写到script标签中的代码都位于全局作用域中
    全局作用域中的变量是全局变量,可以在任意位置访问
  • 局部作用域
    块作用域就是一种局部作用域,在代码块执行时创建,代码块执行完毕它就销毁
    在块作用域中声明的变量是局部变量,只能在块内部访问,外部无法访问

1、函数作用域

函数作用域也是一种局部作用域。函数作用域在函数调用时产生,调用结束后销毁
函数每次调用都会产生一个全新的函数作用域。在函数中定义的变量是局部变量,只能在函数内部访问,外部无法访问

2、函数作用域链

- 当我们使用一个变量时,
​ JS解释器会优先在当前作用域中寻找变量,
​ 如果找到了则直接使用。如果没找到,则去上一层作用域中寻找,找到了则使用
​ 如果还没找到,则继续去上一层寻找,以此类推
​ 如果一直到全局作用域都没找到,则报错 xxx is not defined

五、立即执行函数

- 立即执行函数是一个匿名的函数,并它只会调用一次
​ - 可以利用IIFE来创建一个一次性的函数作用域,避免变量冲突的问题

1
2
3
4
5
(function(){
let a = 10
console.log(111)
}());

六、window对象

在浏览器中,浏览器为我们提供了一个window对象,可以直接访问

window对象代表的是浏览器窗口,通过该对象可以对浏览器窗口进行各种操作
除此之外window对象还负责存储JS中的内置对象和浏览器的宿主对象

window对象的属性可以通过window对象访问,也可以直接访问

函数就可以认为是window对象的方法

1
2
3
4
5
6
7
8
window.a = 10 //向window对象中添加的属性会自动变成全局变量
/*
var 用来声明变量,作用和let相同,但是var不具有块作用域
- 在全局中使用var声明的变量,都会作为window对象的属性保存
- 使用function声明的函数,都会作为window的方法保存
- 使用let声明的变量不会存储在window对象中,而存在一个秘密的小地方(无法访问)
- var虽然没有块作用域,但有函数作用域
*/

七、this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*this
- 函数在执行时,JS解析器每次都会传递进一个隐含的参数
- 这个参数就叫做 this
- this会指向一个对象
- this所指向的对象会根据函数调用方式的不同而不同
1.以函数形式调用时,this指向的是window
2.以方法的形式调用时,this指向的是调用方法的对象
...
- 通过this可以在方法中引用调用方法的对象 */
const obj = {
name: "张三",
sayHello: function () {
console.log(this.name)
},
}
obj.sayHello() //调用时,this就是obj

八、箭头函数补充

1
2
3
4
5
6
7
8
9
1、无参箭头函数:() => 返回值
2、一个参数的:a => 返回值
3、多个参数的:(a, b) => 返回值
4、只有一个语句的函数:() => 返回值
5、只返回一个对象的函数:() => ({...})
6、有多行语句的函数:() => {
....
return 返回值
}