4、函数
4.1、 什么是函数
函数是包裹在花括号中的代码块,前面使用了关键词function:当调用该函数时,会执行函数内的代码。可以在某事件发生时直接调用函数(比如当用户点击按钮时),并且可由JavaScript在任何位置进行调用。
4.2、为什么要用函数
- 提高代码复用
- 便于阅读和交流
4.3、函数的组成
函数名:命名规则同变量名一致。
函数体: 函数的内容,代码块。
参数: 分为形参和实参。
* 形参:声明函数的时候,给的参数, 类似于变量名;在声明函数的时候,参数是没有值。 * 实参:调用函数是给的参数; 实参会按照顺序赋值给形参。
注意1:如果实参数量大于形参数量, 多出来的实参,将被忽略。如果实参数量小于形参数量, 有的形参没有对应的实参,取默认值 undefined。
注意2: JS函数允许形参有默认值,有默认值的形参,在调用函数的时候,可以没有与之对应的实参!
返回值:函数调用表达式的结果
* `函数名()` 被称之为**函数调用表达式**, 表表达式的值就是函数的**返回值**。 * 在函数体内,`return` 右边的表达式(或变量、直接量)便是函数的返回值。 * 函数体内没写 `return` 或者 `return` 的右边是空的,默认默认会返回 `undefined`。 * `return` 除了设置返回值外,还可以结束函数的执行,return 之后的代码不会执行。
4.4、如何定义函数
函数声明
表达式
实例化函数对象
4.5、函数调用(执行)函数
在函数名后面加上 () 就是对函数的调用,函数内的代码会执行。
函数名后面不加() 不会调用函数,函数内的代码也不会执行;函数名本质上是个变量名,通过函数名可以引用到函数本身。
调用函数的四种场景
直接调用
new 操作符
apply
call
- bind
4.6、函数声明提升
函数声明提升:执行代码之前会将先读取函数声明,也就说可以先调用,再声明。
4.7、函数的2种角色
- 函数: 通过()使用
- 对象: 通过.使用 ==> 称之为: 函数对象
4.8、回调函数
- 什么函数才是回调函数?
- 你定义的
- 你没有直接调用
- 但最终它执行了(在特定条件或时刻)
- 常见的回调函数?
- DOM事件函数
- 定时器函数
ajax
回调函数(后面学)- 生命周期回调函数(后面学)
4.9、立即调用函数(IIFE
)
- 理解
- 全称: Immediately-Invoked Function Expression 立即调用函数表达式
- 别名: 匿名函数自调用
- 作用
- 隐藏内部实现
- 不污染外部命名空间
5、函数中的this
5.1、this是什么?
- 一个关键字, 一个内置的引用变量
- 在函数中都可以直接使用this
- this代表调用函数的当前对象
- 在定义函数时, this还没有确定, 只有在执行时才动态确定(绑定)的
5.2、this的指向方式
默认绑定 :常用的函数调用类型:独立函数调用
可以把这个规则看作是无法应用其他规则的时候 默认的规则,基本指向的是window
隐式绑定 :如果函数调用时,前面存在调用它的对象,那么this就会隐式绑定到这个对象上
当函数引用有上下文对象的时候(obj),隐式绑定规则会把函数中的this绑定到这个上下文对象上
隐式绑定可能会出现隐式丢失的问题 :被隐式绑定的函数,会丢失了绑定对象
3.显式绑定: 指我们通过call、apply以及bind方法改变this的行为,相比隐式绑定,我们能清楚的感知 this 指向变化过程。
4.
new
绑定构造函数只是一些使用new操作符被调用的函数,使用new调用函数的时候,会构造一新的对象,这个时候 就把新的对象绑定给了函数的this上
5.3、怎么判断this
- 函数是否在new中调用,如果是的话,this绑定的是新创建的对象
- 函数是否通过call、apply(显示绑定)调用,如果是,则this绑定的是执行的对象
- 函数是否在某个上下文对象中调用(隐式绑定),如果有,则this绑定在这个上下文对象上
- 如果以上都不是 则默认绑定 执行window
6、call、apply和bind
6.1、区别
在JavaScript中,
call
、apply
和bind
是Function
对象自带的三个方法。
call()、apply()、bind() 都是用来重定义 this 这个对象的!
call 、bind 、 apply 传参情况
- call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面
- apply 的所有参数都必须放在一个数组里面传进去
- bind 除了返回是函数以外,它的参数和 call 一样
6.2、手写call
6.3、手写apply
6.4、手写bind
6.5、面试题
function fn1() { console.log(1); } function fn2() { console.log(2); } fn1.call(fn2); fn1.call.call(fn2);