变量提升/函数提升

很多人在初学JS接触到变量,函数的时候,总会碰到一个很棘手的问题----变量/函数提升.

变量提升,顾名思义,就是把定义在后面的变量或者函数,提升到前面来使用.

然而变量提升之所以存在疑点,是因为它涉及到了作用域(scoping)的问题.所以在讲变量/函数提升之前,我们先来研究一下作用域的问题.

JavaScript的scoping如此复杂的原因是它看上去非常像C系语言的成员。我们首先来看一段C程序

#include  
int main() { 
int x = 1; 
printf("%d, ", x); // 1 
if (1) { 
int x = 2; 
printf("%d, ", x); // 2 
} 
printf("%d\n", x); // 1 
} 

这段代码的返回结果是1,2,1. 这是因为在C系语言有块级作用域(block-level scope),当进入到一个块时,就像if语句,在这个块级作用域中声明的新的变量,这些变量不会影响到外部作用域。但是JavaScript却不是这样。
var x = 1; 
console.log(x); // 1 
if (true) { 
var x = 2; 
console.log(x); //2 
} 
console.log(x);// 2 
这段代码的返回结果是1,2,2. 这是因为JavaScript是函数级作用域(function-level scope)。这和C系语言是完全不同的。块,就像if语句,for循环语句,都不会创建一个新的作用域, 只有函数才会创建新的作用域, 而且JS中重复定义变量并不会产生报错,只是新定义的变量值覆盖了之前定义所赋的值。

那么接下来,我们就可以深入的理解一下到底变量/函数提升是怎么一回事了


1.变量提升

变量提升,简单来说,就是把变量提升到一块作用域当中(或者说一个函数)顶端的位置,需要注意的是,变量提升,只是提升变量的声明,并不会将变量的赋值一同提升上来.

比如下面一段代码

(function(){ 
var a='One'; 
var b='Two'; 
var c='Three'; 
})() 
我们定义了3个变量,而事实上,这种写法相当于接下来这段代码

(function(){ 
var a,b,c; 
a='One'; 
b='Two'; 
c='Three'; 
})() 
这就是变量提升的本意.

那么我们来看接下来一段代码,分析看看,这段代码的结果到底应该是什么呢?

 var v='abc';
    alert(v);//①abc
    
   (function(){
        alert(v);//②undefined      
        var v='123';
        alert(v);//③123
    })()

alert(v);//④abc

每一个结果都标注好了,有的朋友会问了,怎么会有一个undefined?

这段代码用一个函数划定了两个作用域,一个是全局,另外一个是函数内,①都被划定在函数外,并不受函数内的定义变量影响,故返回结果都是'abc',而函数内的返回结果,相信你看了下面这个代码段就清楚是怎么一回事了.

  (function(){
        var v;
        alert(v);//②undefined      
        v='123';
        alert(v);//③123
    })()

怎么样?不需要再过多的解释,我相信大家看到这里一定都明白了!


2.函数提升

在我们写js 代码的时候我们有两种写法一种是函数表达式另外一种是函数声明方式。

函数表达式 var fn=function fn(){}

函数声明方式 function fn(){code}

我们需要重点注意的是只有函数声明形式才能被提升。

变量赋值并没有被提升只是声明被提升了。但是函数的声明有点不一样函数体也会一同被提升

函数提升是把整个函数都提到前面去。 

接下来我们看两段代码

(function test3() {
        fn();
        function fn() {
            console.log("我来自fn test3");
        }
    }) ()



function test4() {
        fn();// fn is not a function
        var fn = function fn() {
           console.log("我来自 fn  test4");
        }
        fn();
    }
    test4();

这就是变量/函数提升的全部内容了.如果你有问题,或者还有更好的见解,欢迎评论交流!

 
  
 
  
 
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(变量提升/函数提升)