线理清楚几个概念:
函数的预编译:
一、什么是预编译:
1、函数声明的整体提升(永远会提升在逻辑的最前边)
2、变量声明的提升(只是提升了变量定义的语句,赋值语句是没有提升的)
二、全局变量和局部变量:
1、Imply global(隐式全局变量):及时一个没有经过声明就被赋值的变量,可以在全局(window)的任何地方进行调用。
全局对象(window):为一个
2、全局上的变量,计是声明了也属于window所有,全部是window的属性,window就是全局的域。
预编译:预编译发生在函数执行的前一刻/
预编译的过程:
1、创建AO(activity object)执行期上下文(也就是作用域)
2、找形参和形参值统一
3、将实参值和形参值统一
4、在函数体里面找函数声明,将值赋予函数
全局也会进行预编译,与函数类似,全局会创建一个GO(global object)//也是属于window的一个属性
局部变量调用未定义的元素的时候会像上一级寻找,即,AO里边没有定义但却要引用是会在GO里边进行查找
作用域:
1、A的定义----->会产生一个[scope] 里边会存着这个A的GO
2、这个A在执行的时候会产生一个A的AO,并且把它放在作用域的顶端(类似于堆栈,将之前的GO给挤到下边去)
3、现在A里边访问的变量时,就是访问A的[SCOPE],自顶向下查找。
4、如果A里边有新的定义,那么这个新的定义里面会自动在它的父级基础之上继续生成。
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
//AO产生:----> AO---->f1 a
//进行赋值----> f1=function(){}; a=10;
//按顺序执行,并且调用函数
f1();
var f1 =function() {
console.log(a);
var a = 10;
};
执行结果:
最后一行报错了,因为在定义时只有变量a的前边有var ,b、c前边没有var,也就是说b、c其实就是隐式的全局变量,它的作用范围是全局的,而a前边有var,所以是局部的变量,在调用f1()函数时,默认的AO里边是没有a这个变量的,所以会报错。