执行上下文
-
首先window确定为全局执行上下文
-
全局执行上下文
- 全局数据预处理
- var定义的全局变量==>undefined, 添加为window的属性
function声明
的全局函数==>赋值(fun), 添加为window的方法- this==>赋值(window)
- 函数执行上下文
- 在调用函数, 准备执行函数体之前, 创建对应的函数执行上下文对象
- 对局部数据进行预处理
- 形参变量==>赋值(实参)==>添加为执行上下文的属性
- arguments==>赋值(实参列表), 添加为执行上下文的属性
var定义
的局部变量==>undefined, 添加为执行上下文的属性function声明
的函数 ==>赋值(fun), 添加为执行上下文的方法- this==>赋值(调用函数的对象)
执行上下文栈
- 在全局代码执行前, JS引擎就会创建一个栈来存储管理所有的执行上下文对象
- 在全局执行上下文(window)确定后, 将其添加到栈中(压栈)
- 在函数执行上下文创建后, 将其添加到栈中(压栈)
- 在当前函数执行完后,将栈顶的对象移除(出栈)
- 当所有的代码执行完后, 栈中只剩下window
实例1
//整个过程中产生了几个执行上下文?
//函数调用时才会产生n+1个;n为调用函数的个数,1为window
var a = 10
var bar = function(x) {
var b = 5
foo(x + b)
}
var foo = function(y) {
var c = 5
console.log(a + c + y)
}
bar(10)
//整个过程中产生了3个执行上下文
实例2
console.log('global begin: ' + i)
var i = 1
foo(1);
function foo(i) {
if (i == 4) {
return;
}
console.log('foo() begin:' + i);
foo(i + 1);
console.log('foo() end:' + i);
}
console.log('global end: ' + i)
//输入结果
//global begin:undefined
//foo() begin:1
//foo() begin:2
//foo() begin:3
//foo() end:3
//foo() end:2
//foo() end:1
//global end:1
//整个过程中产生了5个执行上下文?
面试题1
先执行变量提升。再执行函数提升
function a(){}
var a;
console.log(typeof a)//function
面试题2
/*
测试题2: 变量预处理, in操作符
*/
if (!(b in window)) {
var b = 1;
}
console.log(b)//undefined
面试题3
/*
测试题3: 预处理(还没有赋值), 顺序执行
*/
var c = 1 //var c
function c(c) {
console.log(c)
}
//c=1
c(2)//Uncaught TypeError: c is not a function
面试题4
var a = 0,
b = 0;
function A(a) {
A = function(b) {
alert(a + b++);
};
alert(a++);
}
A(1);
A(2);