我已将userid
声明为全局变量,并且在内部函数中给userid
分配了一个值,并声明了一个新函数userid()
,但始终在内部函数声明之前返回。
为什么我不能更改全局变量。
var userid = 'test1';
function foo() {
userid = 'test2';
return;
function userid() {}
}
foo();
console.log(userid);
它返回test1
,但是预期结果应该是test2
。
如果我删除此
function userid() {}
它工作正常。 我知道它的Java脚本“提升”在这里播放,但是为什么以及如何播放?
答案 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()
局部函数,则该变量变量将在本地范围内被覆盖,因为它优先于全局变量。