JavaScript 变量声明提升

    (function() {
        var x=foo();
        var foo=function foo() {
            return 'foobar'
        };
        return x;
    })();

这段代码运行后报错:Uncaught TypeError: foo is not a function

原因在于变量foo的声明提升,后面的赋值,函数表达式不会提升,因此当代码运行到  var x=foo(); 时,

foo()是未定义的。

可以把 var x=foo(); 放到 变量 foo 后再执行:

(function() {
        var foo=function foo() {
            return 'foobar'
        };
        var x=foo();
        return x;
    })();

函数声明整个提升到作用域顶部,比如这样写:

(function() {
        var x=foo();
        function foo() {
            return 'foobar'
        }
        return x;
    })();

再看一个例子:

    var foo = {n:1};
    (function (foo) { //注意这里,传进参数 foo 
        console.log(foo.n);
        foo.n=3; //全局变量重新赋值,
        var foo={n:2}; //局部变量foo进行重新赋值
        console.log(foo.n);
    })(foo);
    console.log(foo.n);//全局变量已经是 n:3
  • 第一步:进行预编译,var全局变量foo、匿名函数 function、var局部变量foo
  • 第二步:代码自上而下、自左向右执行计算:
  1. 对全局变量foo进行赋值foo={n:1};注意:此值为对象,属于引用类型;
  2. 匿名函数传入参数foo={n:1}自执行;
  3. console.log(foo);打出数字1;
  4. 由于存在foo局部变量,那么对foo变量进行赋值foo={n:3},同时更改了引用类型的参数值,全局foo变量被重新赋值foo={n:3};
  5. 对局部变量foo进行重新赋值foo={n:2};
  6. console.log(foo);打出数字2;
  7. 全局变量foo={n:3},因此,console.log(foo);打出数字3;

 

关于var x1=foo(); 和 var x2=foo; 有没括号的区别

函数是一种叫做function引用类型的实例,因此函数是一个对象。对象是保存在内存中的,函数名则是指向这个对象的指针。

函数可以作为参数传入别的函数,也可以作为一个函数的返回值,也可以被重新赋值。

简单来说,x1是函数foo()的返回值,x2是函数foo()本身。

(function() {
        var foo=function foo() {
            return 'foobar'
        };
        var x=foo;
        return x;
    })();
//function foo() { return 'foobar' }    

 

 

 
posted @ 2017-08-05 16:11  kiera  阅读(237)  评论(0编辑  收藏  举报