【问题标题】:why userid not change the global userid , it never used userid function declare inside foo为什么 userid 不更改全局 userid ,它从未在 foo 中使用 userid 函数声明
【发布时间】:2019-10-08 22:41:51
【问题描述】:

我已将userid 声明为全局变量,在函数内部我已为userid 赋值并声明了一个新函数userid(),但始终在内部函数声明之前返回。 为什么我无法更改全局变量。

var userid = 'test1';

function foo() {
	userid = 'test2';
	return;
	function userid() {}
}

foo();
console.log(userid);

它返回test1,但预期结果应该是test2

如果我删除它

function userid() {}

它工作正常。 我知道它的 java 脚本 Hoisting 在这里播放,但为什么以及如何?

【问题讨论】:

  • 你为什么要写这样的东西?这个问题的意义何在?
  • 我真的不明白你为什么要定义一个与变量同名的函数,为什么要在foo()方法内将test2分配给userid。跨度>
  • 我也觉得这个问题很奇怪,但很有趣。如果您删除“function userid() {}”行,它将按预期工作(控制台将显示“test2”。我不得不承认我不知道为什么返回后的那行会改变预期的行为。跨度>
  • 请检查这个答案:stackoverflow.com/questions/26927617/…,它比我能更好地解释“奇怪”的行为。
  • 我正在测试 javascript 提升并发现这种奇怪的行为,我不明白我刚刚声明了本地函数而不是同名变量。

标签: javascript


【解决方案1】:

在 JavaScript 中,声明在其封闭范围的顶部是 hoisted,因此当您声明 function id 时,它的处理方式如下:

function foo() {
    function userid() {} // Even though you placed this last, it's processed first!
    userid = 'test2';
    return;
}
foo();
console.log(userid);

即使您没有将函数作为foo 中的第一件事编写,但它的处理方式就像您编写的一样,这意味着第二个userid 变量现在位于本地范围内并“隐藏”了全球第一。

现在,还有一种方法可以访问全局变量,那就是通过全局 window 对象:

var userid = "something";

function foo() {
  // Hoisting is why we can call functions before we've declared them!
  userid();
  window.userid = 'test2'; // Access the global through the global object
  return;
  // Normally, nothing after a return is processed, but because of 
  // hoisting, this function declaration will be processed first.
  function userid() {
    console.log("hello from userid");
  } 
}
foo();
console.log(userid);

【讨论】:

    【解决方案2】:

    userid() 函数在foo() 函数中声明时,为什么userid 赋值不会改变全局userid

    首先,要理解这一点,您需要知道 函数声明变量声明 都被提升到包含范围的顶部(即函数的顶部, if 是在函数中定义的,或者在全局上下文的顶部(如果在函数之外)。因此,JavaScript 函数可以在声明之前被调用。

    此外,函数声明优先于变量声明,但不高于变量赋值。因此,我们可以说变量赋值覆盖了函数声明。请记住,JS 只提升声明,而不是初始化。

    JS var 语句未在 块级 范围内声明变量(范围为大括号的变量)。相反,它在 function-level 范围内声明变量。这意味着,在函数内声明的变量是局部变量,并且只能在该函数内或由该函数内的函数访问。

    如果您声明了一个同名的全局变量和一个局部变量,当您尝试使用时,局部变量将具有优先权函数内的变量(局部范围)。

    您的代码是变量赋值如何覆盖局部范围中的函数声明的完美示例,让我们分析一下。 p>

    var userid = 'test1'; // Variable initialization not hoisted
    var bar = 'bar1'; 
    
    function foo() {
      console.log('userid-type: ', typeof userid); // userid() Function declaration hoisted 
      // to the top of the local scope
      userid = 'test2'; // Variable assignment into the local scope that overrides the 
      // function declaration.
      console.log('userid-type: ', typeof userid); // Because, when a variable assigment takes 
      // precedence over function declarations, then the variable is hoisted in the local scope.
      // This is why you got that behaviour.
      
      bar = 'bar2';  // Variable assignment to the global scope.
      return;
    
      function userid() {}
    }
    
    foo();
    console.log('userid-value: ', userid);
    console.log('bar-value: ', bar);

    为什么我的代码不使用全局变量。因为userid() 局部函数userid 全局变量同名。然后,当变量赋值发生userid 局部变量退出并属于userid() 局部函数然后这个变量将被覆盖在本地范围内,因为它优先于 全局变量

    【讨论】:

    • JS 不像其他语言那样具有块级作用域(变量作用域为大括号括起来)。 >> 是的,如果你用@987654331 声明你的变量,它就有@关键字。
    • 我知道letconst 具有块级作用域,但在发布版本时我正在考虑var 声明。
    猜你喜欢
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    相关资源
    最近更新 更多