在ECMAScript5中没有块级做用域一说,只有函数做用域和全局做用域,在其中声明的变量和函数和其余语言的展示形式不一样,在某些状况下不必定须要先定义后使用,函数和变量的使用能够在其声明以前,这究竟是怎么回事呢?让咱们一块儿揭开变量声明提早的神秘面纱!!!html
1、变量声明提高浏览器
1 var a = 10; 2 function test() { 3 a = 100; 4 alert(a); 5 alert(this.a); 6 var a; 7 alert(a); 8 } 9 test();
这题考的也是变量声明提高,函数做用域中提早使用变量时必定要注意下面是否有利用var声明,若是有会将其提高,而不是使用外面的全局变量。至关于以下代码:函数
1 var a = 10; 2 function test() { 3 var a; 4 a = 100; 5 alert(a);//100
6 alert(this.a);//10
7 alert(a);//100
8 } 9 test(); 10 //因此输出的结果是 100 10 100
同时要注意在同一做用域内利用var定义多个同名变量若是后面没有赋值,这该变量的值还是上一次所附的值,以下:this
1 var a = 100; 2 var a; 3 console.log(a) // 100
2、函数的声明提高spa
先上题,看看下体应该输出的结果是什么:code
(1)第一题:htm
1 f = function () { return true; }; 2 g = function () { return false; }; 3 (function () { 4 if (g() && [] == ![]) { 5 f = function f() { return false; }; 6 g = function() { return true; } 7 } 8 })(); 9 alert(f());
输出的结果是true ,函数的声明会被提早,可是函数表达式是不会被提早的,在if条件判断中的f和g均为函数表达式,因此均不会被提早,使用全局的变量进行判断,,if中的结果以下:blog
1 var s1 = g();//false
2 var s2 = g() && []; //false
3 var s3 = ![]; //false
4 var s4 = g() && [] == ![]; //false(此处注意运算符的优先级条件运算符的优先级高于逻辑运算,因此先执行后面的,在执行前面的)
5 var s5 = (g() && []) == ![]; //true
6 //因此最后的结果为true。
(2)若是将上面的稍做改变结果会是怎样呢?ip
1 f = function () { return true; }; 2 g = function () { return false; }; 3 (function () { 4 if (g() && [] == ![]) { 5 f = function f() { return false; }; 6 function g() { return true; } //(1) 7 } 8 })(); 9 alert(f());
此题中if中的g函数的声明会被提早,可是定义不会被提早(这个下面将会提到),因此if中使用的将不会 是全局的函数g,而是局部变量,可是虽然g进行了声明,可是没有定义故会报错g is not a function 。若是将(1)式变为 var g = function(){};这样也会报一样的错误,可是后者至关因而函数表达式,提高的是var定义的变量而不是函数的声明,这一点要注意区分的。作用域
3、通过上面的练习你必定好奇函数的声明提早究竟是怎么回事,下面咱们就函数的声明和定义提早好好聊聊(此处将排开函数表达式,由于函数表达式是不会被提早的)
ES5中有规定不要将函数定义在语句块中,也就是函数能够在全局做用域和函数做用域中被声明和定义,但不要在if等语句块中当定义和声明。在全局和函数做用域中定义的函数的声明和定义豆浆会被提早到当前做用域的顶部。可是if,和for中声明的函数在非严格模式下不会报错,可是不一样的浏览器可能表现不一样。在谷歌中,在if 等语句块中声明的函数的声明会被提早可是函数的定义将不会被提早。因此在块语句里面最好是使用函数表达式,而不是函数的声明。
(1) 函数的声明和定义均被提早到当前做用域的顶部
1 f(); 2 function f(){ 3 console.log("ok") 4 } 5 // 输出结果ok 函数的声明和定义均被提早
(2)IIFE中定义的函数(至关于函数中定义的函数)
1 (function(){ 2 f(); 3 function f (){ 4 Console.log(“hello”) 5 } 6 })()
//输出的结果是 hello
(3)if块中定义的函数
1 console.log(f) 2 f(); 3 if(false){ 4 function f(){ 5 console.log("ok") 6 } 7 } //输出undefined后,报错f is not a function 说明在if语句块中的函数的声明被提早可是函数的定义没被提早
(4)for语句块中定义的函数
1 1 console.log(f) 2 2 f() 3 3 for(f();false;){ 4 4 function f(){console.log("ok")}} 5 5 //输出undefined后,报错f is not a function 说明在for语句块中的函数的声明被提早可是函数的定义没被提早
以上即是我的对变量提高的看法若有不足之处,请指教