JavaScript基础知识混乱
大家好,我正在努力理解JavaScript的基本原理,但有一个问题需要解决JavaScript基础知识混乱,javascript,Javascript,大家好,我正在努力理解JavaScript的基本原理,但有一个问题需要解决 var foo = 1; function bar(){ foo = 10; return; function foo(){} } bar(); alert(foo); 这里的alert(foo),将给我1,我知道在return语句之后,函数foo()将不会执行。但现在如果更改代码: var foo = 1;
var foo = 1;
function bar(){
foo = 10;
return;
function foo(){}
}
bar();
alert(foo);
这里的alert(foo)
,将给我1
,我知道在return语句之后,函数foo()将不会执行。但现在如果更改代码:
var foo = 1;
function bar(){
foo = 10;
return;
}
bar();
alert(foo);
在条形函数中,如果我要删除函数foo()
。然后alert(foo)
会给我10
请帮忙,如果有人能解释为什么
我知道在返回语句之后,函数foo()将不会执行
那不是真的
功能声明已悬挂
function foo(){}
创建一个名为foo
的局部变量(将新函数分配给它),然后foo=10
覆盖它。但是,您从未测试该foo
变量的值
在bar函数中,如果我要删除函数foo()。那么alert(foo)会给我10分
您不再有名为foo
的局部变量,因此您将用相同的名称覆盖全局变量
比较:
(函数(){
console.log(“版本1”);
var-foo=1;
功能条(){
log(“在条的顶部,foo是“+foo”);
foo=10;
log(“在bar中赋值后,foo是”+foo);
返回;
函数foo(){}
}
bar();
log(“全局foo是”+foo);
}());
(功能(){
console.log(“版本2”);
var-foo=1;
功能条(){
log(“在条的顶部,foo是“+foo”);
foo=10;
log(“在bar中赋值后,foo是”+foo);
返回;
}
bar();
log(“全局foo是”+foo);
}());代码>所以基本上发生的事情就像您声明了var foo=10
因为javascript中的函数声明被挂在顶部
编译器看到您的代码如下
var foo = 1;
function bar(){
var foo;
foo = 10;
return;
function foo(){}
}
bar();
alert(foo);
所以事实上,foo=10
永远不会覆盖全局foo
;
它保持函数的局部性。
因此,警报将通过全局警报 编写此函数时:
function bar(){
foo = 10;
return;
function foo(){}
}
javascript阅读了以下内容:
function bar(){
function foo(){}
foo = 10;
return;
}
函数foo
被创建到本地函数bar
中。当您写入foo=10
时,您将覆盖局部范围内的函数foo
,而不是全局变量
因此,您的警报为1,因为您从未更新全局变量。这里的问题是和
声明函数foo(){}
被提升,这意味着在这种情况下,即使它写在函数的末尾,它在范围内的任何地方都可用,包括在定义之前
如果函数foo(){}
不存在,则语句foo=10代码>覆盖在全局范围中定义的foo
。因此,全局foo==10
如果存在function foo(){}
,则语句foo=10
只覆盖本地范围内的函数foo
,全局foo
不会被触及,因此全局foo==1
var foo = 1;
function bar(){
console.log(typeof foo) // function
return;
function foo() {}
}
bar();
alert(foo);
反对:
var foo = 1;
function bar(){
console.log(typeof foo) // number
return;
// function foo() {}
}
bar();
alert(foo);
这称为Javascript
我会尽力详细解释的。。这就是我们所拥有的
var foo = 1;
function bar(){
foo = 10;
return;
function foo(){}
}
bar();
alert(foo);
解释器会将其重写为
var foo = 1;
function bar(){
function foo(){} // this is also equal to var foo = function(){};
foo = 10;
return;
}
bar();
alert(foo);
现在给你解释一下被提升的代码
var foo = 1; // global variable;
function bar(){
var foo = function(){}; // foo is local variable of type function
foo = 10; // foo is changed to hold a number
return;
}
bar();
alert(foo); // you alert global variable.
如您所见,如果代码函数foo(){}
存在,它将被视为bar()
范围内的局部变量,对foo
的任何更改都将被视为局部变量更改
- 当在
bar()
中有函数foo(){}
时,您甚至没有触及全局变量。。因此警报1
- 当您没有
函数foo(){}
时,您正在接触全局变量,因此发出警报10
现在我希望你能理解输出
除了我的在同一个线程中,我
添加另一个答案,以提供有关提升的更多详细信息
JavaScript中的特性作为前面的答案已经被OP的内容所接受
首先,让我们熟悉什么是范围界定
JavaScript中的作用域
JavaScript初学者最困惑的一个原因是范围界定。事实上,这不仅仅是初学者。我见过很多经验丰富的JavaScript程序员,他们并不完全理解范围界定。JavaScript中的作用域之所以如此混乱,是因为它看起来像一种C族语言。考虑下面的C程序:
#include <stdio.h>
int main() {
int x = 1;
printf("%d, ", x); // 1
if (1) {
int x = 2;
printf("%d, ", x); // 2
}
printf("%d\n", x); // 1
}
在本例中,Firebug将显示1、2、2。这是因为JavaScript具有函数级作用域。这与C族完全不同。块(如if语句)不会创建新的作用域。只有函数才能创建新的作用域
<> P>对于许多习惯于C语言、C++语言、C语言或java语言的程序员来说,这是意外的,不受欢迎的。幸运的是,由于JavaScript函数的灵活性,有一个解决方法。如果必须在函数中创建临时作用域,请执行以下操作:
function foo() {
var x = 1;
if (x) {
(function () {
var x = 2;
// some other code
}());
}
// x is still 1.
}
这个方法实际上非常灵活,可以在任何需要临时作用域的地方使用,而不仅仅是在块语句中。但是,我强烈建议您花点时间真正理解和欣赏JavaScript的作用域。它非常强大,也是我最喜欢的语言特性之一。如果你了解范围界定,提升对你来说会更有意义
声明、名称和吊装
在JavaScript中,名称以四种基本方式之一进入作用域:
Language defined:
默认情况下,所有作用域都具有此名称和参数
形式参数:
函数可以具有命名形式参数,其作用域为该函数的主体
- 函数声明:它们的形式是
functionfoo(){}
- 可变的
function foo() {
var x = 1;
if (x) {
(function () {
var x = 2;
// some other code
}());
}
// x is still 1.
}
function foo() {
bar();
var x = 1;
}
function foo() {
var x;
bar();
x = 1;
}
function foo() {
if (false) {
var x = 1;
}
return;
var y = 1;
}
function foo() {
var x, y;
if (false) {
x = 1;
}
return;
y = 1;
}
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();