# 变量提升与函数提升
# 变量声明提升(先执行)
- 通过var声明的变量,在定义语句之前就可以访问到
- 值:undefined
# 函数声明提升(后执行)
- 通过function声明的函数,在其之前就可以直接调用
- 值:函数定义(对象)
# 全局执行上下文
- 在执行全局代码前将window确定为全局执行上下文
- 对全局数据进行预处理 * var定义的全局变量==>undefined,添加为window的属性 * function声明的全局函数==>赋值并添加为window的方法 * this指向window
最后执行
# 函数执行上下文
- 在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象
- 对局部数据进行预处理
- 形参变量==>赋值(实参)==>添加为执行上下文的属性
- arguments==>赋值(实参列表),添加为执行上下文的属性
- var定义的局部变量==>undefined,添加为执行上下文的属性
- function声明的函数==>赋值(fun),添加为执行上下文的方法
- this==>赋值(调用函数的对象)
最后执行
# 执行上下文栈
//1.进入全局执行上下文
var a = 10;
var bar = function(x){
var b = 5;
//3.进入foo执行上下文
foo(x+b);
}
var foo = function(y){
var c =5;
console.log(a+c+y);
}
//2.进入bar函数执行上下文
bar(10);
栈流程:1进、2进、3进、3出、2出、1出
# 面试题
(一)
var a = 3;
function fn(){
console.log(a);
var a = 4;
}
fn();
//输出:undefinded
(二)
//1.依次输出了什么?
//2.整个过程中产生了几个执行上下文?
console.log('global begin:'+i);
var i = 1;
foo(i);
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);
//1.依次输出:
// undefined
// foo() begin: 1
// foo() begin: 2
// foo() begin: 3
// foo() end: 3
// foo() end: 2
// foo() end: 1
// global end: 1
//2.整个过程产生了5个执行上下文
//画栈图
//
//foo(4)
//foo(3)
//foo(2)
//foo(1)
//全局执行上下文
(三)
function a(){
}
var a;
console.log(typeof a)
//输出:function
//原因:变量声明提升先执行,函数声明提升后执行覆盖
(四)
var c = 1;
function c(c){
console.log(c);
}
c(2);
//输出:报错 c is not a function
//原因:以上代码相当于
var c;
function c(c){
console.log(c);
}
c = 1;
c(2);
(六)
if(!(b in window)){
var b = 1;
}
console.log(b);
//输出:undefined
//原因:(b in window) === true