zoukankan      html  css  js  c++  java
  • javascript中的变量作用域以及变量提升详细介绍

    在javascript中, 理解变量的作用域以及变量提升是非常有必要的。这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解变量作用域
    “一个变量的作用域表示这个变量存在的上下文。它指定了你可以访问哪些变量以及你是否有权限访问某个变量。”

    变量作用域分为局部作用域和全局作用域。

    局部变量(处于函数级别的作用域)
    不像其他对面对象的编程语言(比方说C++,Java等等),javascript没有块级作用域(被花括号包围的);当是,javascript有拥有函数级别的作用域,也就是说,在一个函数内定义的变量只能在函数内部访问或者这个函数内部的函数访问(闭包除外,这个我们过几天再写个专题)。

    函数级别作用域的一个例子:


    复制代码代码如下:

    var name = "Richard";

    function showName () {
        var name = "Jack"; // local variable; only accessible in this showName function
        console.log (name); // Jack
    }
    console.log (name); // Richard: the global variable

    没有块级作用域:


    复制代码代码如下:

    var name = "Richard";
    // the blocks in this if statement do not create a local context for the name variable
    if (name) {
        name = "Jack"; // this name is the global name variable and it is being changed to "Jack" here
        console.log (name); // Jack: still the global variable
    }

    // Here, the name variable is the same global name variable, but it was changed in the if statement
    console.log (name); // Jack

    //    不要忘记使用var关键字
    //    如果声明一个变量的时候没有使用var关键字,那么这个变量将是一个全局变量!
    // If you don't declare your local variables with the var keyword, they are part of the global scope
    var name = "Michael Jackson";

    function showCelebrityName () {
        console.log (name);
    }

    function showOrdinaryPersonName () {    
        name = "Johnny Evers";
        console.log (name);
    }
    showCelebrityName (); // Michael Jackson
    // www.jbxue.com 
    // name is not a local variable, it simply changes the global name variable
    showOrdinaryPersonName (); // Johnny Evers

    // The global variable is now Johnny Evers, not the celebrity name anymore
    showCelebrityName (); // Johnny Evers

    // The solution is to declare your local variable with the var keyword
    function showOrdinaryPersonName () {    
        var name = "Johnny Evers"; // Now name is always a local variable and it will not overwrite the global variable
        console.log (name);
    }
    //    局部变量优先级大于全局变量
    //如果在全局作用域中什么的变量在局部作用域中再次声明,那么在局部作用域中调用这个变量时,优先调用局部作用域中声明的变量: 
    var name = "Paul";

    function users () {
        // Here, the name variable is local and it takes precedence over the same name variable in the global scope
    var name = "Jack";

    // The search for name starts right here inside the function before it attempts to look outside the function in the global scope
    console.log (name); 
    }

    users (); // Jack

    全局变量
    所有在函数外面声明的变量都处于全局作用域中。在浏览器环境中,这个全局作用域就是我们的Window对象(或者整个HTML文档)。

    每一个在函数外部声明或者定义的变量都是一个全局对象,所以这个变量可以在任何地方被使用,例如:

    复制代码代码如下:

    // name and sex is not in any function
    var myName = "zhou";
    var sex = "male";

    //他们都处在window对象中
    console.log(window.myName); //paul
    console.log('sex' in window); //true


    如果一个变量第一次初始化/声明的时候没有使用var关键字,那么他自动加入到全局作用域中。

    复制代码代码如下:

    function showAge(){
      //age初始化时没有使用var关键字,所以它是一个全局变量
      age = 20;
      console.log(age);
    }

    showAge();  //20
    console.log(age); //因为age是全局变量,所以这里输出的也是20

    setTimeout中的函数是在全局作用域中执行的

    setTimeout中的函数所处在于全局作用域中,所以函数中使用this关键字时,这个this关键字指向的是全局对象(Window):

    复制代码代码如下:

    var Value1 = 200;
    var Value2 = 20;
    var myObj = {
      Value1 : 10,
      Value2 : 1,

      caleculatedIt: function(){
        setTimeout(function(){
          console.log(this.Value1 * this.Value2);
        }, 1000);
      }
    }

    myObj.caleculatedIt(); //4000

    为了避免对全局作用域的污染, 所以一般情况下我们尽可能少的声明全局变量。  
    变量提升(Variable Hoisting)
    所以的变量声明都会提升到函数的开头(如果这个变量在这个函数里面)或者全局作用域的开头(如果这个变量是一个全局变量)。我们来看一个例子:

    复制代码代码如下:

    function showName () {
    console.log ("First Name: " + name);
    var name = "Ford";
    console.log ("Last Name: " + name);
    }

    showName (); 
    // First Name: undefined
    // Last Name: Ford

    // The reason undefined prints first is because the local variable name was hoisted to the top of the function
    // Which means it is this local variable that get calls the first time.
    // This is how the code is actually processed by the JavaScript engine:

    function showName () { // www.jbxue.com
        var name; // name is hoisted (note that is undefined at this point, since the assignment happens below)
    console.log ("First Name: " + name); // First Name: undefined

    name = "Ford"; // name is assigned a value

    // now name is Ford
    console.log ("Last Name: " + name); // Last Name: Ford
    }

    函数声明会覆盖变量声明
    如果存在函数声明和变量声明(注意:仅仅是声明,还没有被赋值),而且变量名跟函数名是相同的,那么,它们都会被提示到外部作用域的开头,但是,函数的优先级更高,所以变量的值会被函数覆盖掉。

    复制代码代码如下:

    // Both the variable and the function are named myName
    var myName;?
    function myName () {
    console.log ("Rich");
    }

    // The function declaration overrides the variable name
    console.log(typeof myName); // function

    但是,如果这个变量或者函数其中是赋值了的,那么另外一个将无法覆盖它:

    复制代码代码如下:

    // But in this example, the variable assignment overrides the function declaration
    var myName = "Richard"; // This is the variable assignment (initialization) that overrides the function declaration.

    function myName () {
    console.log ("Rich");
    }

    console.log(typeof myName); // string

    最后一点, 在严格模式下,如果没有先声明变量就给变量赋值将会报错!

  • 相关阅读:
    百度AI开放平台 情感倾向分析实例以及gbk编码解决
    根据cid获取哔哩哔哩弹幕
    python3 doc2vec文本聚类实现
    python3 LDA主题模型以及TFIDF实现
    偶得李春芬先生书信一函
    STATA一小步 我的一大步
    2013-2015南京大学历史学系若干考试题目汇编
    ArcPy批量计算Mean Center的两个实例
    解决Gephi导入csv文件时提示“边表格需要一个包含节点标号‘源’和‘目标’列” 问题的两个方案
    Vertx 实现webapi实战项目(二)
  • 原文地址:https://www.cnblogs.com/linuxnotes/p/3387207.html
Copyright © 2011-2022 走看看