本文参考:深入理解 Javascript 一书。
https://www.gitbook.com/book/wtser/deep-learn-javascript/details
JavaScript 执行上下文(Execution Contexts):
简介
每次当控制器转到ECMAScript可执行代码的时候,即会进入到一个执行上下文。执行上下文(简称-EC)是ECMA-262标准里的一个抽象概念,用于同可执行代码(executable code)概念进行区分。
标准规范没有从技术实现的角度定义EC的准确类型和结构,这应该是具体实现ECMAScript引擎时要考虑的问题。
活动的执行上下文组在逻辑上组成一个堆栈。堆栈底部永远都是全局上下文(global context),而顶部就是当前(活动的)执行上下文。堆栈在EC类型进入和退出上下文的时候被修改(推入或弹出)。
补充
- 在某些时刻,可执行代码与执行上下文完全有可能是等价的
- 上下文是从英文context翻译过来,指的是一种环境。
- 在软件工程中,上下文是一种属性的有序序列,它们为驻留在环境内的对象定义环境。
JavaScript的执行上下文的理解是一种大概模糊的理解(译者)。 - 上下文的原意是content,而作用域的原意是scope。
scope:函数被调用的时候, 各个变量的作用区域
content:函数被调用的时候, 查看this指向哪个object, 那么那个object 就是当前的 “上下文”。
JavaScript this关键字
定义
- this是执行上下文中的一个属性
- this与上下文中可执行代码的类型有直接关系,this值在进入上下文时确定,并且在上下文运行期间永久不变。
全局代码中的this
在全局代码中,this始终是全局对象本身,这样就有可能间接的引用到它了。
函数代码中的this
在函数代码中使用this时很有趣,这种情况很难且会导致很多问题。
这种类型的代码中,this值的首要特点(或许是最主要的)是它不是静态的绑定到一个函数。
正如我们上面曾提到的那样,this是进入上下文时确定,在一个函数代码中,这个值在每一次完全不同。
在通常的函数调用中,this是由激活上下文代码的调用者来提供的,即调用函数的父上下文(parent context )。this取决于调用函数的方式。
引用类型和this为null
一个函数上下文中确定this值的通用规则如下:
在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用括号()的左边是引用类型的值,this将设为引用类型值的base对象(base object),在其他情况下(与引用类型不同的任何其它属性),这个值为null。不过,实际不存在this的值为null的情况,因为当this的值为null的时候,其值会被隐式转换为全局对象。注:第5版的ECMAScript中,已经不强迫转换成全局变量了,而是赋值为undefined。
那么就引入了一下问题:
1、什么是引用类型的值?
- 处理一个标示符
- 处理一个属性访问器
2、标识符有哪些?
- 在JS中所有的可以由我们自主命名的都可以称为是标识符
例如:变量名、函数名、属性名都属于标识符 - JavaScript 保留的一些关键字
作为构造器调用的函数中的this
new运算符调用“A”函数的内部的[[Construct]] 方法,接着,在对象创建后,调用内部的[[Call]] 方法。 所有相同的函数“A”都将this的值设置为新创建的对象。
函数调用中手动设置this
在函数原型中定义的两个方法(因此所有的函数都可以访问它)允许去手动设置函数调用的this值。它们是.apply和.call方法。他们用接受的第一个参数作为this值,this 在调用的作用域中使用。这两个方法的区别很小,对于.apply,第二个参数必须是数组(或者是类似数组的对象,如arguments,反过来,.call能接受任何参数。两个方法必须的参数是第一个——this。