1.变量提升:
通过var定义(声明)的变量,在定义之后就可以访问到值,undefined
2.函数提升
通过function声明的函数,在之前就可以直接调用
面试题:
var a = 3;
function fn () {
console.log(a);
var a = 4;
}
fn() //undefined
当调用fn这个函数的时候,执行打印变量a,首先会在fn的作用域中寻找,由于在下面是var变量
会在函数中首先定义,不过值是undefined
console.log(b); // 在前面可以访问到,不过值是undefined
fn2();//可以调用
fn3();//不能调用 这个地方是变量提升
var b = 3;
function fn2() {
console.log('fn2')
}
var fn3 = function () {
console.log('fn3');
}
在var b是相当于在window的全局作用域声明了b,不过值是undefined。并且fn2函数也已经执行(不是调用)
用function定义的函数已经预处理执行了,但是fn3的函数还未执行,未函数提升
3.全局执行上下文
在执行全局代码将window确定为全局执行上下文
对全局数据进行预处理
var定义的全局变量 定义为undefined
function声明的全局变量 添加为window的方法
this赋值为window
console.log(a1); //undefined
a2() //a2
console.log(this); //window
var a1 = 3
function a2(){
console.log('a2()');
}
4.函数执行上下文
在调用函数准备函数之前,创建对应函数执行上下文
对局部数据进行预处理
形参变量 赋值 添加上下文执行属性
arguments 赋值 添加上下文执行属性
var定义的局部变量 undefined
fucntion声明的函数 赋值 添加上下文方法
this赋值调用函数的对象
function fn (a1) {
console.log(a1); //2
console.log(a2); //undefined
a3();//a3()
a4()//a4 is not a function
console.log(this);//windiw
console.log(arguments);//2,3 类数组 伪数组
var a2 = 3
function a3() {
console.log('a3()');
}
var a4=function(){
console.log('a4()')
}
}
fn(2,3)
因为赋值给a1=2; 因为a3是function声明的函数,函数提升所以可以调用;因为a4是定义函数没有函数提升,只有变量提升;因为fn是window调用,所以this是window;arguments是2,3伪数组
5.执行上下文栈
1.在全局代码执行前,js引擎就会创建一个栈来管理存储所有的执行上下文对象
2.在全局执行上下文window确定后,将其添加到栈中(压栈)
3.在函数执行上下文创建后,将其添加到栈中(压栈)
4.在函数执行完之后,将栈顶的对象移除(出栈)
5.在当前函数执行完之后,栈中只剩window
因为执行函数的时候才会产生上下文,window,bar,foo依次入栈
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)
}
面试题:
1.
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 beginundefined
//foo()begin1
//foo()begin2
//foo()begin3
//foo() end3
//foo() end2
//foo() end1
//global end1
因为是栈结构,所以后进先出
2.
function a(){}
var a;
console.log(typeof a);
先变量提升并赋值 undefined,然后函数提升并覆盖掉变量提升赋值的undefined,所以为 'function'
3.
if(!b in window) {
var b = 1;
}
console.log(b); //undefined
因为b经过变量提升在window对象中,所以b in window是true,所以不能进去if判断,所以不能直接执行,所以b是undefined
4.
var c =1;
function c(c){
console.log(c)
}
c(2);
首先进行变量提升undefined,后再进行函数提升,再赋值c=1,然后得到最终结果是c is not a function