Javascript函数范围和提升

Javascript函数范围和提升,javascript,scope,scoping,hoisting,Javascript,Scope,Scoping,Hoisting,我刚刚读了一篇关于他的好文章,他在文章中举了以下例子: var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a); 使用上述代码,浏览器将提示“1” 我仍然不确定它为什么返回“1”。他说的一些话让我想起: 所有的功能声明都被提升到顶部。可以使用函数限定变量的作用域。还是不适合我 您必须记住的是,它在执行之前解析整个函数并解析所有变量声明。所以 function a() {}

我刚刚读了一篇关于他的好文章,他在文章中举了以下例子:

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}
b();
alert(a);
使用上述代码,浏览器将提示“1”

我仍然不确定它为什么返回“1”。他说的一些话让我想起:
所有的功能声明都被提升到顶部。可以使用函数限定变量的作用域。还是不适合我

您必须记住的是,它在执行之前解析整个函数并解析所有变量声明。所以

function a() {} 
真的变得

var a = function () {}
var a
强制它进入局部作用域,变量作用域贯穿整个函数,因此全局a变量仍然是1,因为您已通过将a作为函数声明为局部作用域

函数a(){}
是一个函数语句,它创建一个
a
变量,该变量位于
b
函数的局部。
解析函数时会创建变量,而不管是执行
var
还是函数语句


a=10
设置此局部变量。

函数
a
在函数
b
内提升:

var a = 1; 
function b() { 
   function a() {} 
   a = 10; 
   return;
} 
b(); 
alert(a);
这几乎就像使用
var

var a = 1; 
function b() { 
   var a = function () {};
   a = 10; 
   return;
} 
b(); 
alert(a);

函数是在本地声明的,设置
a
仅在本地范围内发生,而不是在全局变量中发生。

函数提升意味着函数被移动到其范围的顶部。就是

function b() {  
   a = 10;  
   return;  
   function a() {} 
} 
将被interpeter改写为

function b() {
  function a() {}
  a = 10;
  return;
}
奇怪吧

而且在这个情况下,

function a() {}
表现与

var a = function () {};

因此,本质上,代码就是这样做的:

var a = 1;                 //defines "a" in global scope
function b() {  
   var a = function () {}; //defines "a" in local scope 
   a = 10;                 //overwrites local variable "a"
   return;      
}       
b();       
alert(a);                 //alerts global variable "a"
  • 函数声明
    function a(){}
    首先被提升,其行为类似于
    var a=function(){},因此在本地范围
    中创建了一个
    
    
  • 若有两个同名变量(一个在全局变量中,另一个在局部变量中),则局部变量始终优先于全局变量
  • 设置
    a=10
    时,设置的是局部变量
    a
    ,而不是全局变量

  • 因此,全局变量的值保持不变,您会收到警报1,因为变量名与函数名的意思是“a”相同。 因此,由于Javascript的原因,它尝试解决命名冲突,它将返回a=1

    在我读到这篇关于“JavaScript提升”的文章之前,我对此也感到困惑


    希望能有所帮助。

    提升是一个让我们更容易理解的概念。实际发生的是声明首先针对其作用域进行,然后赋值(而不是同时进行)

    当声明发生时,
    var a
    ,然后
    function b
    ,在该
    b
    范围内,声明
    function a

    此函数a将对来自全局范围的变量a进行阴影处理

    声明完成后,将开始赋值,全局
    a
    将获得值
    1
    ,函数b
    中的a将获得
    10
    。 执行
    警报(a)
    时,它将调用实际的全局范围变量。 对代码的这一小改动将使其更加清晰

            var a = 1;
    
        function b() {
            a = 10;
            return a;
    
            function a() { }
        }
    
        alert(b());
        alert(a);
    

    以下是我对答案的重述,并附有更多注释和一把可供玩弄的小提琴

    // hoisting_example.js
    
    // top of scope ie. global var a = 1
    var a = 1;
    
    // new scope due to js' functional (not block) level scope
    function b() {
        a = 10; // if the function 'a' didn't exist in this scope, global a = 10
      return; // the return illustrates that function 'a' is hoisted to top
      function a(){}; // 'a' will be hoisted to top as var a = function(){};
    }
    
    // exec 'b' and you would expect to see a = 10 in subsequent alert
    // but the interpreter acutally 'hoisted' the function 'a' within 'b' 
    // and in doing so, created a new named variable 'a' 
    // which is a function within b's scope
    b();
    
    // a will alert 1, see comment above
    alert(a);
    

    scpope、关闭和吊装(变量/功能)

  • scpope:全局变量可以在任何地方(整个文件)访问 范围),本地变量只能由本地 范围(功能/块范围)
    注意:如果局部变量不使用 var关键字在一个函数中,它将成为一个全局变量
  • 闭包:另一个函数内部的函数,可以访问 本地作用域(父函数)和全局作用域,以及它的变量 其他人无法访问!除非您将其作为返回值返回
  • 提升:将所有声明/取消声明变量/函数移动到范围 顶部,然后指定值或null
    注意:它只移动声明,不移动值
    var a=1;
    //“a”是全球范围
    函数b(){
    var a=函数(){};
    //“a”是局部范围
    var x=12;
    //“x”是局部范围
    a=10;
    //全局变量“a”被局部变量“a”覆盖
    console.log(“本地a=“+a”);
    返回console.log(“本地x=“+x”);
    }       
    b();
    //本地a=10
    //局部x=12
    console.log(“全局a=“+a”);
    //全局a=1
    log(“无法访问本地x=\n”);
    //无法访问本地x=
    控制台日志(x);
    
    //ReferenceError:x未定义
    这段代码中的争论焦点是什么

    案例1:

    函数a(){}
    定义包含在
    函数b
    的主体中,如下所示<代码>记录a=1的值
  • var a = 1;
    function b() {
      a = 10;
      return;
    
      function a() {}
    }
    b();
    console.log(a); // logs a = 1
    
    案例2

    函数a(){}
    定义排除在
    函数b
    的主体中,如下所示<代码>记录a=10的值

    var a = 1;
    function b() {
      a = 10;  // overwrites the value of global 'var a'
      return;
    }
    b();
    console.log(a); // logs a = 10
    
    观察将帮助您认识到该语句
    console.log(a)
    记录以下值

    案例1:a=1

    案例2:a=10

    假设

  • var a
    已在全局范围内按词汇定义和声明
  • a=10
    此语句将值重新指定为10,它在词汇上位于函数b内部 两种情况的解释

    因为带有name属性的
    函数定义
    a与
    变量a
    相同。
    函数体b中的
    变量a
    成为局部变量。前一行表示a的全局值保持不变,而a的局部值更新为10

    所以,我们想说的是下面的代码

    var a = 1;
    function b() {
      a = 10;
      return;
    
      function a() {}
    }
    b();
    console.log(a); // logs a = 1
    
    它由JS解释器解释如下

    var a = 1;
    function b() {
      function a() {}
      a = 10;
      return;
    
    
    }
    b();
    console.log(a); // logs a = 1
    
    但是,当我们删除
    var a = 1;
    function b() {
      var a = 10; // here var a is declared and defined locally because it uses a var keyword. 
      return;
    }
    b();
    console.log(a); // logs a = 1
    
    var a = 1;
    function b() {
      a = 10; // here var a is declared and defined locally because it uses a var keyword. 
      return;
    
      function foo() {}
    }
    b();
    console.log(a); // logs a = 1
    
     a = 5; // Assign 5 to a
     elem = document.getElementById("demo"); // Find an element 
     elem.innerHTML = a;                     // Display a in the element
     var a; // Declare a
      //output-> 5
    
     var a = 5; // Assign and declare 5 to a
     elem = document.getElementById("demo"); // Find an element 
     elem.innerHTML = a;                     // Display a in the element
      // output -> 5
    
      function foo() {
         console.log(x)
         var x = 1;
     }
    
      function foo() {
         var x;
         console.log(x)
         x = 1;
      }
    
      function foo() {
         if (false) {
             var a = 1;
         }
         return;
         var b = 1;
      }
    
      function foo() {
          var a, b;
          if (false) {
            a = 1;
         }
         return;
         b = 1;
      }
    
     function demo() {
         foo(); // this will give error because it is variable hoisting
         bar(); // "this will run!" as it is function hoisting
         var foo = function () {
             alert("this would not run!!");
         }
         function bar() { 
             alert("this will run!!");
         }
     }
     demo();
    
    var a = 1;
    function b() {
      a = 10;
      return;
       function a() {}
    }
    b();
    alert(a);
    
    var a = 1;                 //defines "a" in global scope
     function b() {  
       var a = function () {}; //defines "a" in local scope 
        a = 10;                 //overwrites local variable "a"
        return;      
     }       
     b();       
     alert(a); 
    
    function a(){
      function b(){
        console.log(myVar);
      }
    
      var myVar = 2;
      b();
    }
    
    var myVar = 1;
    a();
    b();
    > 2
    > Uncaught ReferenceError: b is not defined
    
    function a(){
      function b(){
        console.log(myVar);
      }
    
      b();
    }
    
    var myVar = 1;
    a();
    > 1
    
    a = 7;
    var a;
    console.log(a) 
    
    var a;
    a = 7;
    console.log(a);
    // 7
    
    console.log(square(7)); // Output: 49
    function square(n) { return n * n; }
    
    function square(n) { return n * n; }
    console.log(square(7)); // 49
    
    console.log(x);
    var x = 7; // undefined
    
    var x;
    console.log(x); // undefined
    x = 7;
    
     var v;
     console.log(v);
     console.log(abc);
    /*
    The output of the above codes are:
    undefined
    ReferenceError: abc is not defined*/
    
    <script>
    var totalAmo = 8;
    var getSum = function(a, b){
          return a+b;
    }
    </script>
    
    console.log(totalAmo);
    console.log(getSum(8,9));
    var totalAmo = 8;
    var getSum = function(a, b){
          return a+b;
    }
    console.log(totalAmo);
    console.log(getSum(9,7));
    
     <script>
            var totalAmo;
            var getSum;
    
            console.log(totalAmo);
            console.log(getSum(8,9));
            var totalAmo = 8;
            var getSum = function(a, b){
                return a+b;
            }
            console.log(totalAmo);
            console.log(getSum(9,7));
        </script>
    
    console.log(getId());
    function getId(){
       return 739373;
    }
    /* output: 739373, because the whole function hoisted on the top of the scope.*/
    
    function functionScope(){
                var totalAmo;
                var getSum;
    
                console.log(totalAmo);
                console.log(getSum(8,9));
                var totalAmo = 8;
                var getSum = function(a, b){
                    return a+b;
                }
            }
    
     function getTotal(){
                let total=0;
                for(var i = 0; i<10; i++){
                    let valueToAdd = i;
                    var multiplier = 2;
                    total += valueToAdd*multiplier;
                }
                return total;
            }
    
     function getTotal(){
                let total;
                var multiplier;
                total = 0;
                for(var i = 0; i<10; i++){
                    let valueToAdd;
                    valueToAdd = i;
                    multiplier = 2;
                    total += valueToAdd*multiplier;
                }
                return total;
            }