一.JS变量提升
1.当浏览器引擎解析js代码时,将js中的所有一开始就是var声明的和function声明的都提升到全局。此时又叫全局作用域
1 console.log(aa); 2 console.log(ff); 3 console.log(bb); 4 5 var aa = "aa"; 6 7 function ff(){ 8 console.log("ff"); 9 }
注意:undefined和is not defined是不一样的。
-
undefined:声明了该变量但是调用时没有定义值
-
is not defined:没有声明也没有定义值
2.对于函数也一样,又叫做局部作用域
1 function ff(){ 2 3 console.log(aa); 4 console.log(fun); 5 console.log(bb); 6 var aa = "aa"; 7 function fun(){} 8 9 } 10 11 ff();
3.作用域分类
-
全局作用域
-
函数作用域
-
块作用域(ES6才有)
注:查找作用域先从当前作用域查找再找上层作用域
例1:
1 var x = 10; 2 function fn() { 3 console.log(x); 4 } 5 function show(f) { 6 var x = 20; 7 f(); 8 } 9 show(fn); //10
分析:
- 全局作用域
- var x
- function fn
- function show
- 函数作用域fn
- 函数作用域show
- var x
注意此处两个函数作用域是同一级的
执行到console.log(x)时,会先看fn()的函数作用域内是否有x变量没有就出去看全局的(由于show和fn为同一级所以不会看show),则此时x = 10;
例2:
1 var fn = function () { 2 console.log(fn) 3 } 4 fn() 5 6 var obj = { 7 fn2: function () { 8 console.log(fn2) 9 } 10 } 11 obj.fn2()
分析:
- 全局作用域:
- var fn
- var obj
- 全局中无函数作用域
第一个fn():会执行console.log(fn)在函数中没有fn,找全局发现fn变量是一个函数则返回函数
第二个obj.fn2():会执行console.log(fn2)在函数中没有发现fn2,不回去找obj对象中的fn2由于没有对象作用域这个东西,则找全局也没有找到报错了。
如果稍微修改以下将fn2改为this.fn2则不会报错,绑定调用对象obj然后调用obj的fn2。
1 var fn = function () { 2 console.log(fn) 3 } 4 fn() 5 6 var obj = { 7 fn2: function () { 8 console.log(this.fn2) 9 } 10 } 11 obj.fn2()