资料来源
js代码的执行过程
执行上下文的产生
调用栈
用来管理执行上下文的栈称为执行上下文栈,又称调用栈。
var a = 2
function add(b,c){
return b+c
}
function addAll(b,c){
var d = 10
result = add(b,c)
return a+result+d
}
addAll(3,6)
执行上面的代码,它的调用栈就是这样的
栈溢出,当分配的调用栈空间被占满时就会出现这个问题。
作用域
作用域就是变量与函数的可访问范围,js的作用域有三种:全局作用域、函数作用域、块级作用域。
- 全局作用域中的对象在代码中的任何地方都能访问,其生命周期伴随着页面的生命周期。
- 函数作用域就是在函数内部定义的变量或者函数,并且定义的变量或者函数只能在函数内部被访问。函数执行结束之后,函数内部定义的变量会被销毁。
词法作用域链
代码查找变量的过程是沿着一条链进行查找的,这条链称为词法作用域链。词法作用域是由代码中函数声明的位置来决定的,在代码编译阶段就决定好的,和函数调用的位置是没有关系的。
闭包
内部函数访问外部函数声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了,但是内部函数引用外部函数的变量依然保存在内存中,则称内部函数是外部函数的闭包。
function foo() {
var myName = "极客时间"
let test1 = 1
const test2 = 2
var innerBar = {
getName:function(){
console.log(test1)
return myName
},
setName:function(newName){
myName = newName
}
}
return innerBar
}
var bar = foo()
bar.setName("极客邦")
bar.getName()
console.log(bar.getName())
闭包使用原则
如果该闭包会一直使用,那么它可以作为全局变量而存在;但如果使用频率不高,而且占用内存又比较大的话,那就尽量让它成为一个局部变量。
this
全局执行上下文的this
全局执行上下文中的 this 是指向 window 对象的。这也是 this 和作用域链的唯一交点,作用域链的最底端包含了 window 对象,全局执行上下文中的 this 也是指向 window 对象。
函数执行上下文的this
普通函数中的 this 默认指向全局对象 window
改变函数执行上下文的this的指向
1、通过call、apply、bind函数设置
2、通过对象调用方法设置
var myObj = {
name : "极客时间",
showThis: function(){
console.log(this)
}
}
myObj.showThis()
使用对象来调用其内部的一个方法,该方法的 this 是指向对象本身的。
3、通过构造函数设置
```js
function CreateObj(){
this.name = "极客时间"
}
var myObj = new CreateObj()