zoukankan      html  css  js  c++  java
  • 理解javascript作用域及hosting机制

    在javascript中, 理解变量的作用域以及变量提升是非常有必要的,特别是对于初学者,很容易莫名地就掉坑里。

    一、javaScript作用域

    在C语言中,一对花括号{}代表一个独立的作用域,我们称之为块级作用域。一个块级作用域中,只作用于该块的变量可以被声明,只会影响快内而不会影响块外面的作用域。javaScript没有块级作用域,只有全局作用域和函数作用域。

    全局作用域其实是全局对象的作用域,任意地方都可以访问到。函数对象作用域跟C的局部变量作用域是不同的,它的作用域是整个函数范围,在函数内声明的所有变量在函数体内始终是可见的。

    下面我们吃些栗子来加深理解:

    栗子代码1:

    var x='我是只锅';//声明一个全局变量x
    console.log(x);//‘我是只锅’
    if(1){
      var x='我是只灰色的锅';
      console.log(x);//‘我是只灰色的锅’
    }
    console.log(x);//‘我是只灰色的锅’

    在if语句里面改变了变量x的值,全局变量x也就改变了,说明{}没有建立新的作用域,而是处于全局作用域中的,由此可见javascript跟        C的作用域是不一样的。对于全局作用域的变量,无论是在if语句内还是函数内都可以访问到;

    栗子代码2:

    function a(){
        var arg='我是只锅';
    }
    console.log(arg);//浏览器报错:arg is not defined

    arg变量是在函数a内声明的,函数外没有声明,无法获取到arg变量,所以浏览器报错。说明函数对象作用域,只有在函数体内才可以访问,而函数体外是不能访问。

    栗子代码3:

    var arg='我是只锅';
    function a(){
        console.log(arg);//undefined
        var arg='我是只灰色的锅';
        console.log(arg);//‘我是只灰色的锅’
    }
    a();

             这里应该很多童靴可能会认为第三行会输出“我是只锅”,因为代码还没有执行到var语句声明arg的地方。然而并非如此,这到底是为什么呢?这里就引申出javascript作用域的一个特性:hosting机制。

    二、hosting机制

    所谓的hoisting,也就是变量提升的概念。变量提升即将变量声明提升到它所在作用域的最开始的部分。在javaScript中,变量和函数的声明会提升到最顶部执行。

    由于函数作用域的特性,局部变量在整个函数体内始终是有定义的。因此在上面的栗子3中,函数体内局部变量arg遮盖了同名全局变量arg。不过,只是声明提前了,赋值执行是没有被提前的,所以第三行会输出undefined。由此,上面的过程相当于这样:

    var arg='我是只锅';
    function a(){
        var arg;
        console.log(arg);//undefined
        arg='我是只灰色的锅';
        console.log(arg);//‘我是只灰色的锅’
    }
    a();

    下面我们接着吃些栗子来深剖一下hosting的特点:

    (1)函数声明提升高于变量声明

    栗子代码1:

    console.log(typeof a);//function
    var a;
    function a(){
        ...
    }

    栗子代码2:

    console.log(typeof a);//function
    function a(){
        ...
    }
    var a;

    同时定义变量a和函数a,无论是先定义函数还是后定义函数,最后a显示的都是函数,证明function的优先级高于var。

    (2)匿名函数不会向上提升

    栗子代码:

    console.log(typeof a);//undefined
    var a=function (){
        ...
    }

    匿名函数这种形式其实就是var变量的声明定义,因此第一行输出结果为undefined,应该是可以理解的。

    (3)不同代码块中的函数互不影响

              栗子代码:

    <script>//代码块1
        console.log(typeof a);//undefined
        var a=function (){
            ...
        }
    </script>
    
    <script>//代码块2
        function a(){
            ...
        }
    </script>

    代码块1中的a,输出的是undefined,说明代码块2的函数a没有被提前到代码块1之前,由此可见不同代码块之间函数是互不影响的。

  • 相关阅读:
    最小生成树之算法记录【prime算法+Kruskal算法】【模板】
    hdoj 1869 六度分离【最短路径求两两边之间最长边】
    la3211
    codeforces round #414 div1+div2
    bzoj1823
    bzoj3112
    bzoj1061&&bzoj3256
    单纯形&&线性规划
    bzoj1494
    bzoj3105
  • 原文地址:https://www.cnblogs.com/huiguo/p/7966937.html
Copyright © 2011-2022 走看看