一、js执行原理
var name = "why"
console.log(num1);
var num1 = 20
var num2 = 30
var result = num1 + num2
console.log(result);
1.代码在运行前会先被解析,V8引擎(引擎因浏览器而异)内部会创建一个对象(GlobalObject简称为go)
var GlobalObject = {
String: "类",
Date: "类",
setTimeout: "函数",
window: globalObject,
name: undefined,
num1: undefined,
num2: undefined,
result: undefined
}
2.运行代码
- v8引擎为了执行代码内部会创建一个执行上下文栈(函数调用栈)
- 因为我们执行的是全局代码,为了全局代码能够正常执行需要创建一个全局执行上下文(全局代码需要被执行时才会创建)
3.函数执行过程
var name = "why"
foo(123)
function foo(num){
console.log(m) //undefined
var m = 10
var n = 20
console.log("foo") //foo
}
- 代码在被解析时V8引擎会创建一个对象(GlobalObject简称为go)
var GlobalObject = {
String: "类",
window: globalObject,
name: undefined,
foo: 0xa00(内存地址)
}
- js引擎遇到函数时会独立创建一个空间存储函数(存储函数的父级作用域和函数代码块)
- 当函数被调用时(foo())会通过GO对象找到函数的内存地址,通过内存地址找到存储函数的空间,将函数(函数有独立的执行上下文)放入全局执行上下文栈
- 当函数执行完时,函数的执行上下文会弹出栈且销毁
二、作用域链
- 当我们查找一个变量时,真实的查找路径是沿着作用域链来查找的
var name = "why"
foo(123)
function foo(num){
console.log(m)
var m = 10
var n = 20
function bar(){
console.log(name)
}
bar()
}
- 当函数被调用时(foo())会通过GO对象找到函数的内存地址,通过内存地址找到存储函数的空间,将函数(函数有独立的执行上下文)放入全局执行上下文栈
- 执行到bar函数时又会开辟一个bar函数的执行上下文
- 当bar函数执行完时,函数的执行上下文会弹出栈且销毁,这时foo函数也执行完后该执行上下文也会弹出栈且销毁