在此之前,先了解一下执行上下文:
理解执行上下文
JavaScript中代码是分段执行的,控制器转到每段可执行代码时,就会进入一个执行上下文,执行上下文可以理解为当前代码的执行环境,执行环境有三种情况:
- 全局环境: JavaScript代码执行会首先进入该环境。
- 函数环境:当函数被调用执行时,会进入该函数的执行环境。
- eval()(不建议使用,可以忽略)
我们只需要考虑全局执行环境和函数执行环境,JavaScript引擎会通过栈的方式来处理执行环境,栈底永远都是全局执行环境,栈顶是当前正在执行的函数执行环境。
注意:在函数中,遇到return就会直接结束可执行代码的执行,将当前上下文弹出栈。
在执行上下文的创建阶段,会执行以下操作:
- 生成变量对象
- 确定this指向
- 建立作用域链
这里我们先暂时只讨论this的指向问题。
关于this的指向,请牢记准则:
this的指向是在函数调用的时候确定的,函数定义时无法确定。
1 | var name = 'global'; |
除此之外,在函数的执行过程中,this一旦被确定,就不可更改了。
知其然还要知其所以然,所以我们先分析一下this的指向。
作为构造函数执行
1 | function Foo (name) { |
new 一个对象的过程:
- 创建一个新对象
- this指向这个对象
- 执行代码,即对this赋值
- 返回this
作为对象属性执行
1 | const obj = { |
作为普通函数执行
1 | function foo () { |
call
1 | function foo (name) { |
apply
1 | function foo (name, age) { |
bind
1 | // 注意:这里不能使用函数声明式写法,只能用函数表达式写法 |