当代码在一个环境中执行时,会创建变量对象的一个作用域链。
作用域链的用途是,保证对执行环境有权访问的所有变量和函数的有序访问。
标识符解析是沿着作用域链一级一级的搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐步的向后回溯,知道找到标识符为止。
例1:
<ul id="test"> <li>第1个li元素</li> <li>第2个li元素</li> <li>第3个li元素</li> </ul> <script type="text/javascript"> var eles = document.getElementById(‘test‘).getElementsByTagName(‘li‘); for(var i=0; i<eles.length; i++){ eles[i].onclick = function(){ this.style.color="#f3f33f"; console.log(i); } } </script>
解析:
点击任意一个标签,弹出的都是3这个数字
因为在点击li对应的函数中,并没有i这个变量的存储空间,此时需要向上查找,到for这一级,由于for循环的进行,全局下的变量i值已经为eles.length
例2:
<ul id="test"> <li>第1个li元素</li> <li>第2个li元素</li> <li>第3个li元素</li> </ul> <script type="text/javascript"> var eles = document.getElementById(‘test‘).getElementsByTagName(‘li‘); for (var i = 0; i < eles.length; i++) { eles[i].onclick = function(num) { console.log(i); // 0 1 2 return function() { console.log(num); } }(i); } </script>
解析:
第一个console.log 因为函数自执行,将当前的i值循环存储下来。
第二个console.log 在点击时会弹出相应函数的变量。在当前函数中没有num的存储空间,会向上一级作用域查找,然后使用之前存储的值。