JavaScript进阶之this

本文参考:深入理解 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值在进入上下文时确定,并且在上下文运行期间永久不变。
    JavaScript进阶之this

全局代码中的this

在全局代码中,this始终是全局对象本身,这样就有可能间接的引用到它了。
JavaScript进阶之this

函数代码中的this

在函数代码中使用this时很有趣,这种情况很难且会导致很多问题。
这种类型的代码中,this值的首要特点(或许是最主要的)是它不是静态的绑定到一个函数
正如我们上面曾提到的那样,this是进入上下文时确定,在一个函数代码中,这个值在每一次完全不同。
在通常的函数调用中,this是由**上下文代码的调用者来提供的,即调用函数的父上下文(parent context )。this取决于调用函数的方式
JavaScript进阶之this

引用类型和this为null

一个函数上下文中确定this值的通用规则如下:
在一个函数上下文中,this由调用者提供,由调用函数的方式来决定。如果调用括号()的左边是引用类型的值,this将设为引用类型值的base对象(base object),在其他情况下(与引用类型不同的任何其它属性),这个值为null。不过,实际不存在this的值为null的情况,因为当this的值为null的时候,其值会被隐式转换为全局对象。注:第5版的ECMAScript中,已经不强迫转换成全局变量了,而是赋值为undefined。

那么就引入了一下问题:
1、什么是引用类型的值?

  • 处理一个标示符
  • 处理一个属性访问器

2、标识符有哪些?

  • 在JS中所有的可以由我们自主命名的都可以称为是标识符
    例如:变量名、函数名、属性名都属于标识符
  • JavaScript 保留的一些关键字

JavaScript进阶之this

作为构造器调用的函数中的this

JavaScript进阶之this
new运算符调用“A”函数的内部的[[Construct]] 方法,接着,在对象创建后,调用内部的[[Call]] 方法。 所有相同的函数“A”都将this的值设置为新创建的对象。

函数调用中手动设置this

在函数原型中定义的两个方法(因此所有的函数都可以访问它)允许去手动设置函数调用的this值。它们是.apply和.call方法。他们用接受的第一个参数作为this值,this 在调用的作用域中使用。这两个方法的区别很小,对于.apply,第二个参数必须是数组(或者是类似数组的对象,如arguments,反过来,.call能接受任何参数。两个方法必须的参数是第一个——this。
JavaScript进阶之this