JavaScript - Function
闭包
闭包是一个
绑定了执行环境
的函数
,JavaScript 中的函数完全符合
闭包的定义
在 JavaScript 中,与
闭包
对应的概念就是函数
执行上下文
- 执行上下文:
执行一段代码(包括函数),所需要的所有信息
- 相比于普通函数,
JavaScript 函数
的主要复杂性
来源于其携带的环境部分
版本
ES3
Key | Desc |
---|---|
scope |
作用域、作用域链 |
variable object |
变量对象,用于存储变量的对象 |
this value |
this 值 |
ES5
Key | Desc |
---|---|
lexical environment |
词法 环境,当获取 变量时使用 |
variable environment |
变量 环境,当声明 变量时使用 |
this value |
this 值 |
ES2018 - Recommend
this value
被纳入lexical environment
Key | Desc |
---|---|
lexical environment |
词法 环境,当获取 变量或者 this 值时使用 |
variable environment |
变量 环境,当声明 变量时使用 |
code evaluation state |
用于恢复代码执行位置 |
Function |
执行的任务是函数 时使用,表示正在被执行的函数 |
ScriptOrModule |
执行的任务是脚本 或者模块 时使用,表示正在被执行的代码 |
Realm |
使用的基础库 和内置对象实例 |
Generator |
仅生成器 上下文有这个属性,表示当前生成器 |
var
通过创建一个函数,并且
立即执行
,来构造一个新的域
,从而控制var
的范围
使用
()
1 | (function () { |
使用
void
- 推荐
有效避免了语法
问题,并且void
在语义上表示忽略
后面表达式的值,变成undefined
1 | void function () { |
声明的变量与被赋值的变量可能会
不一致
,要借助with
(不推荐使用)
1 | var b; |
let
从
ES6
开始引入let
,JavaScript 在运行时
引入了块级作用域
在let
之前,JavaScript 的if
、for
等语句都不产生作用域
for
if
switch
try/catch/finally
函数
切换执行上下文
的主要场景:函数调用
普通函数
使用
function
关键字定义的函数
1 | function foo() { |
箭头函数
使用
=>
运算符定义的函数
1 | let foo = () => console.log("hello js"); |
方法
在
class
中定义的函数
1 | class Human { |
生成器函数
使用
function*
定义的函数
1 | function* generator(i) { |
类
使用
class
定义的类,实际上也是函数
1 | class Human { |
异步函数
在
普通函数
、箭头函数
和生成器函数
加上async
关键字
1 | async function f1() { |
this
行为
this
是执行上下文
中很重要的一个组成部分,同一个函数调用方式
不同,得到的this
也不同
1 | function showThis() { |
普通函数
的this
由调用它所使用的引用
决定的- 获取
函数的表达式
,实际上返回的并非函数本身,而是一个Reference
类型Reference
类型的组成:一个对象
+一个属性值
Reference
类型中的对象
被当作this
值,传入到执行函数时的上下文
当中
调用函数时使用的引用,决定了函数执行时刻的 this 值
- 从
运行时
角度来看,this 与 OOP 毫无关联
,而是与函数调用
时使用的表达式
有关
如果使用
箭头函数
,不论用什么引用来调用它,都不会影响this
值
1 | let showThis = () => console.log(this); |
方法
1 | class C { |
机制
TBD
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.