为什么userid不能更改全局userid,却从未在foo

时间:2019-05-22 12:31:30

标签: javascript

我已将userid声明为全局变量,并且在内部函数中给userid分配了一个值,并声明了一个新函数userid(),但始终在内部函数声明之前返回。 为什么我不能更改全局变量。

var userid = 'test1';

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

foo();
console.log(userid);

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

如果我删除此

function userid() {}

它工作正常。 我知道它的Java脚本“提升”在这里播放,但是为什么以及如何播放?

2 个答案:

答案 0 :(得分:3)

在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);

答案 1 :(得分:1)

为什么在userid函数中声明了userid函数时,userid()分配不会更改全局foo()

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

此外,函数声明优先于变量声明,但不优先于变量分配。因此,可以说变量赋值会覆盖函数声明。请记住,JS仅提升声明,而不初始化。

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

如果您声明具有相同名称的全局变量局部变量,则在尝试使用局部变量时将具有优先级函数(局部范围)中的变量。

您的代码是一个完美的示例,我们将分析变量赋值如何覆盖本地范围中的功能声明

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() 局部函数,则该变量变量将在本地范围内被覆盖,因为它优先于全局变量