[英]Javascript- Variable Hoisting
这是一个简单的片段,我只是不明白的东西。
下面的代码输出12,我理解,因为var foo = 12;
替换先前的变量声明。
<script>
var foo = 1;
function bar(){
if (!foo) {
var foo = 12;
}
alert(foo);
}
bar();
</script>
在下面的代码中,它会发出警报1 ,这意味着在函数内部可以访问在函数外部声明的变量。
<script>
var foo = 1;
function bar(){
alert(foo);
}
bar();
</script>
但是,在下面的代码中,为什么它会提示undefined? 我想,它会警告1 ,我只是将之前声明的变量分配给新的变量。
<script>
var foo = 1;
function bar(){
if (!foo) {
var foo = foo;
}
alert(foo);
}
bar();
</script>
变量声明被推送到函数的开头。
因此实际上发生了以下情况:
function bar(){
var foo;
if (!foo) {
foo = foo;
}
alert(foo);
}
因此,您需要将其更改为使用window.foo
以便您引用全局属性而不是函数的属性:
var foo = 1;
function bar(){
var foo;
if (!window.foo) {
foo = window.foo;
}
alert(foo);
}
bar();
吊装有点棘手。 函数声明随函数赋值一起提升,但变量声明在没有变量赋值的情况下被提升。 所以代码的执行顺序实际上是:
var foo;
var bar = function bar(){
var foo; // undefined
if (!foo) { // true
foo = foo; // foo = undefined
}
alert(foo);
}
foo = 1;
bar();
如果要引用全局变量foo
,可以使用window.foo
,或者更好,只需使用不同的变量名:
var foo = 1;
function bar(){
var baz = foo;
alert(baz);
}
bar();
下面的代码输出12,我理解,因为var foo = 12; 替换先前的变量声明。
var foo = 1;
function bar(){
if (!foo) {
var foo = 12;
}
alert(foo);
}
bar();
你是对的,因为局部变量覆盖了全局变量。
在下面的代码中,它会发出警报1,这意味着在函数内部可以访问在函数外部声明的变量。
var foo = 1;
function bar(){
alert(foo);
}
bar();
你是对的。 foo
在全局范围内声明,因此可以从任何地方访问。
但是,在下面的代码中,为什么它会提示undefined? 我想,它会警告1,我只是将之前声明的变量分配给新的变量。
var foo = 1;
function bar(){
if (!foo) {
var foo = foo;
}
alert(foo);
}
bar();
这有点不同。 您正在声明一个全局变量和一个具有相同名称的本地变量。 当您的JavaScript程序执行进入一个新函数时,函数中任何位置声明的所有变量都会被移动(或提升或提升)到函数的顶部。
另一个例子:
var a = 123; function f() { var a; // same as: var a = undefined; alert(a); // undefined a = 1; alert(a); // 1 } f();
在javascript中,直到ES5规范,范围仅在函数体方面实现。 块范围的概念不存在( 实际上,将使用let关键字在下一个javascript中实现 )。
所以,如果你声明一个变量var something;
在函数体之外,它将是全局的(在浏览器全局范围内是window对象的范围)。
var something = 'Hi Man'; /** * this is equal to: **/ window.something = 'Hi Man';
如果您的代码不以严格模式运行,则还有另一种声明全局变量的方法:省略var关键字。 省略var关键字时,变量属于(或移动)到全局范围。
something = 'Hi Man'; /** * this is equal to: **/ function someFunction() { something = 'Hi Man'; }
因为块范围的不存在,声明局部变量的唯一方法是在函数体中定义它。
var something = 'Hi Man'; //global console.log('globalVariable', something); function someFunction() { var something = 'Hi Woman'; console.log('localVariable', something); /** * defining variable that doesn't exists in global scope **/ var localSomething = 'Hi People'; console.log('another local variable', localSomething); } someFunction(); console.log('globalVariable after function execution', something); try { console.log('try to access a local variable from global scope', localSomething); } catch(e) { console.error(e); }
正如您在此示例中所看到的,局部变量不在其范围之外。 这意味着另一件事......如果使用var关键字在两个不同的范围中声明相同的变量,您将获得两个不同的变量,而不是覆盖父范围中定义的相同变量(名称)。
如果要在子范围中 “覆盖”相同的变量,则必须在不使用var关键字的情况下使用它。 由于范围链,如果局部范围中不存在变量,则将在其父范围内搜索。
function someFunction() { something = 'Hi Woman'; } var something = 'Hi Man'; console.log(1, 'something is', something); someFunction(); console.log(1, 'something is', something);
正如我在下面所写,目前,没有任何方法可以在代码的某些方面声明变量。 它始终在范围的开头声明。
function someFunction() { // doing something // doing something else var something = 'Hi Man'; } /** * Probably you expect that the something variable will be defined after the 'doing * something else' task, but, as javascript works, it will be defined on top of it scope. * So, the below snippet is equal to: **/ function someFunction1() { var something; // doing something // doing something else something = 'Hi Man'; } /** * You can try these following examples: * * In the someFunction2 we try to access on a non-defined variable and this throws an * error. * * In the someFunction3, instead, we don't get any error because the variable that we expect to define later will be hoisted and defined at the top, so, the log is a simple undefined log. **/ function someFunction2() { console.log(something); }; function someFunction3() { console.log('before declaration', something); var something = 'Hi Man'; console.log('after declaration', something); }
发生这种情况是因为在javascript中有两个不同的变量声明步骤:
而function3示例如下:
function3Explained() { var something; // define it as undefined, this is the same as doing var something = undefined; // doing something; // doing something else; something = 'Hi Man'; }
恕我直言,它与功能声明和吊装没有任何关系,
使用var
inside函数声明var,你在函数的隔离范围中创建一个变量,这就是你未定义的原因。
var foo = 1;
function funcOne() {
var foo = foo;
alert('foo is ' + foo);
};
funcOne();
var bau = 1;
function funcTwo() {
bau = bau;
alert('bau is ' + bau);
};
funcTwo();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.