变量提升和函数提升

转载:http://www.cnblogs.com/sun-mile-rain/p/4029816.html

1. 变量声明提升

      先看以下代码:

1)var in_window = "a" in window; console.log(in_window); 

2)var in_window = "a" in window; console.log(in_window); if(!("a" in window)) { var a = 1; }

3)var a; var in_window = "a" in window; console.log(in_window); if(!("a" in window)) { a = 1; }

      控制台输出的结果分别是:false true true。如何解释? 这是由于在js的变量作用域中有个规则:所有变量声明都在范围作用域的顶部!也就是说,在2)代码中,if语句块内的申明的变量a,会自动提到上面去申明。其等价于3)。

      由上述的分析可知,可以理解下面代码的输出结果是undefined。

      if(!("a" in window)) { var a = 1; } console.log(a); //undefined  该代码其实相当于:var a; if(!("a" in window")) { a = 1; } console.log(a);

      再试一次:

var s = '';
if ( false) {
     var a = 1;
}

      浏览器中的调试结果如下:

      有图有真相。变量a的声明的确提升了。

      巩固题: 

      var s = ''; while(false) { var a = 1; } console.log(a); //undefined

      if(!("a" in window)) { a = 1 } console.log(a); //1

      console.log(a); //报错,"ReferenceError: a is not defined."

2. 函数声明提升

      定义函数有两种方式:一种是函数申明,另一种是函数表达式。函数申明形式:function functionName(arg0, arg1, arg2) { //函数体 },函数表达式形式:var functionName = function(arg0, arg1, arg2) { //函数体 } 。关于函数申明,它有一个重要特征就是函数声明提升,看下面的例子。

sayHi();
function sayHi() {
    console.log("hi");
}

      浏览器中的调试结果如下: 发现函数sayHi已经被声明了,并且其值为sayHi函数。第一行代码执行后,输出hi。

 

      若采用函数表式的形式,此时我们能看到变量声明提升的效果。

sayHi();
var sayHi =  function() {
    console.log("hi");
}

      在浏览中的调试效果如下:发现变量sayHi提升了,它的值是undefined,第一行代码执行的话,会报错:"TypeError:undefined is not a function"。

      接下来的例子就很好理解。

      if(!("a" in window)) { var a = function() { window.a = 1; } } console.log(a); //undefined 该代码等价于: var a; if(!("a" in window)) { a = function() { window.a = 1; } } console.log(a); 其实无论if语句块中的a被定义成何种类型的值,a的申明都提前了。(变量提升)

      将上述代码变形如下:

      if(!("a" in window)) { function a() { window.a = 1; }} console.log(a); //function a() { window.a = 1;}(函数申明提升)

      由此可以总结出,所有函数声明也在范围作用域的顶部。那么函数声明和变量声明,哪个的优先级高呢?

3. 变量声明 VS 函数声明

      如下图对比所示:函数声明会覆盖变量声明。

     VS      VS    

      但是如果在变量声明的同时,对变量进行初始化,情况会有所不同。对同一个变量名,声明变量同时初始化变量优先级高于函数

    VS      VS   

      再练几题:

function a() {  return  false; }
var s = '';
if(a()) {
     var a = 1;
}
console.log(a);

      上述代码输出的a值为:function a() { return false; }

function a() {  return  true; }
var s = '';
if(a()) {
     var a = 1;
}
console.log(a);

      上述代码输出的a值为:1

function a() {  return  true; }
var a;
var s = '';
if(a()) {
    a = 1;
}
console.log(a);

      上述代码输出的a值为:1

      由对上述代码的分析:可以总结出如下规律:

1)变量声明提升变量申明在进入执行上下文就完成了。

      只要变量在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;

2)函数声明提升执行代码之前会先读取函数声明,意味着可以把函数申明放在调用它的语句后面。

      只要函数在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部;

3)变量or函数声明函数声明会覆盖变量声明,但不会覆盖变量赋值。

      同一个名称标识a,即有变量声明var a,又有函数声明function a() {},不管二者声明的顺序,函数声明会覆盖变量声明,也就是说,此时a的值是声明的函数function a() {}。注意:如果在变量声明的同时初始化a,或是之后对a进行赋值,此时a的值变量的值。eg: var a; var c = 1; a = 1; function a() { return true; } console.log(a); //1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值