一、es6前javascript中分为全局作用域和局部作用域
1.全局作用域:在整个script标签中有效或者js文件中
2.局部作用域:也叫做函数作用域,这个变量只在函数内部起作用效果。
如果全局变量和局部变量的名字相同了,由于其作用的范围不一样,因此不会互相影响
注意区别:1.在函数内部直接赋值而没有声明的变量也属于全局变量,全局调用有效果;
2.函数的形参也可以看作是局部变量
3.执行效果:全局变量只有浏览器关闭的时候才会销毁,比较占资源;局部变量当程序执行完毕就会销毁,较节约内存
二、作用域链式访问:
内部函数可以访问外部函数变量采用链式访问
如下所示:输出结果就是离输出语句最近的为20
var num=10;
function fn(){
var num=20;
function fun(){
console.log(num);
// 会先找离它最近外层的num,如果没找到,则再往外找。
}
}
三、预解析
js代码分为预解析和代码执行,预解析会将所有的var和function提升到当前作用域的最前面,再按照代码的执行顺序执行。
如下:
console.log(num);//报错
console.log(num);
var num=10;//undefine
function fn(){
console.log(11);
}//调用放在函数前还是函数后都可以执行
fun();
var fun=function(){//调用放在函数函数后可以执行,放在前不行
console.log(22);
} */
四、预解析案例
例子1:判断输出结果
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
结果为:
分析:相当于下面分析过程
步骤1, 将变量预解析和函数预解析提前到当前作用域最前面,所以函数里面的变量赋值不用提到最外面, 其他语句按顺序
var num;
function fun() {
console.log(num);
var num = 20;
}
num = 10;
fun();
步骤2: 将函数里面的变量赋值提到他所在的作用域最前面
var num;
function fun() {
var num
console.log(num);
num = 20;
}
num = 10;
fun();
例子2:
var num = 10;
function fn() {
console.log(num);
var num = 20;
console.log(num);
}
fn();
结果为:
分析结果如下
var num = 10;
function fn() {
var num
console.log(num);
num = 20;
console.log(num);
}
num = 10;
fn();
例子3: (部分面试题)
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;//相当于var a=9;b=9;c=9,在函数中,仅赋值没声明相当于全局变量
//不等于var a=9,var b=9;var b=9
console.log(a);
console.log(b);
console.log(c);
}
结果为:
分析如下:关键在于var a=9;b=9;c=9,在函数中,仅赋值没声明相当于全局变量
不等于var a=9,var b=9;var b=9
function f1() {
var a;
a = b = c = 9;//相当于var a=9;b=9;c=9,在函数中,仅赋值没声明相当于全局变量
//不等于var a=9,var b=9;var b=9
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);//报错