这里主要记录在平常中对知识的学习,经过结合笔记与自身理解的方式尝试写下总结
文章对细节可能不会一一介绍解释,内容仅做参考
复制代码
上次写了做用域相关的知识总结,这篇文章是它的进一步提高。若是对做用域还不是很了解,能够先看一下:JavaScript做用域相关的总结javascript
我翻了挺多文章,感受他们对上下文这个词的解释都有些抽象,不如干脆就放过他的字面意义,而是记住他是如何产生的,以及做用java
当JavaScript执行一段可执行代码时,就会先创建对应的执行上下文app
执行上下文的代码会分红两个阶段进行:函数
在生成的每一个执行上下文中,都会有3个重要的属性:post
变量对象是与执行上下文相关的数据域,存储了在上下文中定义的变量和函数声明学习
在进入执行上下文时(未代码执行),变量对象会进行初始化,包括:ui
举个栗子:this
function a(n, m) {
var b = 1
function c() {
console.log('c')
}
var d = function() {
console.log('d')
}
b = 2
}
a(10, 20)
复制代码
在进入执行上下文后,此时的变量对象是这样的:spa
变量对象 = {
arguments: {
0: 10,
1: 20,
length: 2
},
n: 10,
m: 20,
b: undefined,
c: function, d: undefined } 复制代码
等到了代码执行时,代码会顺序执行,从而更改变量对象的值。当代码执行到最尾时,变量对象是这样的:code
变量对象 = {
arguments: {
0: 10,
1: 20,
length: 2
},
n: 10,
m: 20,
b: 1 -> 2,
c: function, d: functionExpression } 复制代码
在函数中,当查找变量的时候,会先从当前上下文的变量对象中查找,若是没有找到,就会从父级(词法层面)执行上下文的变量对象查找,一直找到全局上下文的变量对象。这样由多个执行上下文的变量对象构成的链表就叫作做用域链
在做用域总结中已经提过,对于一个变量的查找方向是在做用域定义的时候就已经约定好的
JavaScript有一套不一样于其余语言的对this的处理机制。在五种不一样的状况下,this指向的各不相同
常见误解
Foo.method = function() {
function test() {
console.log(this)
}
test() // window
}
复制代码
这里会被认为test函数中的this会指向Foo对象,实际上不是这样子的,而是会指向全局对象。若是想拿到Foo的内部this,能够这样写
Foo.method = function() {
let that = this
function test() {
console.log(that)
}
test() // Foo
复制代码
let a = {
b: function() {
console.log(this.c)
},
c: 1
}
let mb = a.b
mb() // undefined (指向window)
复制代码
另外一个看起来奇怪的地方是函数别名,也就是将一个方法赋值给一个变量。上例中b 就像一个普通的函数被调用。所以,函数内的 this 不被指向到 a 对象,而是全局对象
以上三个属性构成了执行上下文的做用,使得在代码执行时可以使用相关的特性