函数变量提升

在 JS 里,声明函数只有 2 种方法:
第 1 种: function foo(){...} (函数声明)
第 2 种: var foo = function(){...} (等号后面必须是匿名函数,这句实质是函数表达式)

除此之外,类似于 var foo = function bar(){...} 这样的东西统一按 2 方法处理,即在函数外部无法通过 bar 访问到函数,因为这已经变成了一个表达式。

但为什么不是 "undefined"?
这里如果求 typeof bar ,会返回 undefined,但求的是 typeof bar(),所以会去先去调用函数 bar(),这里就会直接抛出异常,因为找不到bar函数,所以是 Error。
看下面这个例子:
1.   var f = function g() {
            return 23;
          };
    typeof g();
如果是typeof f,结果是function.  (这里的f其实是函数名)
如果是typeof f(),结果是number.   (f()指的是函数运行后的结果)
如果是typeof g,结果是undefined.
如果是typeof g(),结果是ReferenceError,g is not defined

2.    (function() {

            var x=foo();

            var foo=function foo() {
                            return “foobar”
                      };
            return x;
        })();
就相当于 

        (function() {

              var x=foo();

              var foo=function () {
                            return “foobar”
                      };
              return x;
          })();
会当作函数表达式来处理,调用要在函数表达式之后才能使用,不然会报错(函数声明可以提前调用函数)
函数声明可以被提前,但函数表达式不能被提前
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.块级作用域
for(var i=0;i<3;i++){
... ...
}
console.log('i='+i);//i=3
JavaScript没有块级作用域。
(function(){
//块级作用域
}))();
模拟块级作用域,避免全局变量污染。
2.var
(1)变量声明
在全局作用域中声明的变量、函数会变成window对象的属性和方法。
使用var声明的全局变量不可删除;
省略var声明的全局变量就不是window的属性了,可删除。
var a = 1;
window.b = 2;
c = 3;
this.d = 4;
var aa = Object.getOwnPropertyDescriptor(window,'a'); //configurable:false,enumerable:true,value:2,writable:true
var bb = Object.getOwnPropertyDescriptor(window,'b'); //configurable:true,enumerable:true,value:2,writable:true
var cc = Object.getOwnPropertyDescriptor(window,'c'); //configurable:true,enumerable:true,value:2,writable:true
var dd = Object.getOwnPropertyDescriptor(window,'d'); //configurable:true,enumerable:true,value:2,writable:true
delete a; // 无法删除
delete b; // 可删除
delete c; // 可删除
delete d; // 可删除
(2)声明提升
console.log(n);//undefined
var n=3;
(3)重复变量声明

使用var语句重复声明语句是合法且无害的,JavaScript会忽略同一变量的后续声明。

3.源码分析
if(! "a" in window){
var a = 1;
}
alert(a);
等价于
var a;
if(!"a"in window){
a =1;
}
alert(a);
(1)JavaScript无块级作用域,在全局作用域中声明变量a为window的属性;
(2)window存在属性a,if语句不成立,a=1赋值语句不执行;
(3)弹出变量a为undefined;
posted @ 2017-03-10 17:01  我啊我  阅读(179)  评论(0编辑  收藏  举报