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;

大家好,我正在努力理解JavaScript的基本原理,但有一个问题需要解决

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