关于js的变量提升(hoisting)

javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。
案例1

var v = "hello";
(function(){
  console.log(v);
  var v = "world";
})();

输出的结果为:undefined。不是hello也不是not defined

案例2

var v = "hello";
if(true){
  console.log(v);
  var v = "world";
}

结果为:hello。

上面两个案例说明了:javascript是没有块级作用域的。函数是JavaScript中唯一拥有自身作用域的结构。

  • 另外,在js中不用var 声明的变量都是全局变量,而且是顶层对象window的属性。不过在js严格模式下是会报错的。
2、关于声明函数两种形式的变量提升

请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:

(function(){
  //var f1,function f2(){}; //hoisting,被隐式提升的声明
 
  f1(); //ReferenceError: f1 is not defined
  f2();
 
  var f1 = function(){};
  function f2(){}
})();
  • 只要函数声明f2被提升,变量f1也被提升但提升为undefined,执行到函数表达式处才被赋值的。

最后来一个小案例:

<html>  
<head>  
<script type="text/javascript">  
function buttonInit(){  
    for(var i=1;i<4;i++){  
        var b=document.getElementById("button"+i);  
        b.addEventListener("click",function(){ alert("Button"+i);},false);  
    }  
}  
window.onload=buttonInit;  
</script>  
</head>  
<body>  
<button id="button1">Button1</button>  
<button id="button2">Button2</button>  
<button id="button3">Button3</button>  
</body>  
</html>  

当文档加载完毕,给几个按钮注册点击事件,当我们点击按钮时,会弹出什么提示框呢?

很容易犯错,对是的,三个按钮都是弹出:"Button4",你答对了吗?

当注册事件结束后,i的值为4,当点击按钮时,事件函数即function(){ alert("Button"+i);}这个匿名函数中没有i,根据作用域链,所以到buttonInit函数中找,此时i的值为4,

所以弹出”button4“。

以上转载自原文地址

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容