人总是喜欢自己没有的
一个有趣的现象 let
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <ul > <li > 111</li > <li > 222</li > <li > 333</li > <li > 444</li > <li > 555</li > </ul > <script > var lis = document .querySelectorAll("li" ); for (let i=0 ; i< lis.length; i++) { var li = document .querySelectorAll("li" )[i]; li.onclick = function ( ) { alert(i); } } </script >
var
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <ul > <li > 111</li > <li > 222</li > <li > 333</li > <li > 444</li > <li > 555</li > </ul > <script > var lis = document .querySelectorAll("li" ); for (var i=0 ; i< lis.length; i++) { var li = document .querySelectorAll("li" )[i]; li.onclick = function ( ) { alert(i); } } </script >
问题 在不使用let的情况下, 如何使点击每个li弹出对应的序号 事件委托 事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown……)的函数委托到另一个元素; 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <ul id ="list" > <li > 111</li > <li > 222</li > <li > 333</li > <li > 444</li > <li > 555</li > </ul > <script > document .getElementById('list' ).addEventListener('click' , function (e ) { var event = e || window .event; var target = event.target || event.srcElement; if (target.nodeName.toLocaleLowerCase() === 'li' ) { console .log('the content is: ' , target.innerHTML); } }); </script >
let let定义变量时和var有两个区别:块级作用域、不会变量提升和不能定义在块中已有标识符同名的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function getValue (condition ) { if (condition) { let value = "blue" ; return value; } else { return null ; } }
当用let定义value时,我们只能在if里面才能访问到value了,value变量也不会变量提升,从而我们在else里面不能访问到value。 let最常用的场景应该是for循环了:
1 2 for (let i = 0 ; i < len; i++) {}
块级作用域 块级作用域就不用多说,就是用let定义的变量只在定义它的块中有效,出了这个块你就不能访问到它了。 变量提升 变量提升应该是在面试的时候会经常考到,例如:
1 2 3 4 5 6 7 8 9 <script> function test ( ) { console .log(value); var value = 'something' ; console .log(value); } test(); </script>
我们用let重新定义上面的test()函数:
1 2 3 4 5 6 7 8 9 <script> function test ( ) { console .log(value); let value = 'something' ; console .log(value); } test(); </script>
同名变量 用var定义变量时,我们可以多次对它进行定义,例如:
1 2 3 var a = 1 ;var a = 2 ;var a = 3 ;
这样的代码是不会报错的,在let定义的相同块中定义同名变量时就会报错了,例如:
1 2 3 4 5 6 7 let a = 1 ;let a = 2 ;var a = 1 ;let a = 2 ;
要注意的是要与let定义时在相同的块中,下面的代码是不会出错的:
1 2 3 4 var a = 1 ;if (something) { let a = 2 ; }
var 我们知道在ES6之前,是没有块级作用域这一说的,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function getValue (condition ) { if (condition) { var value = "blue" ; return value; } else { return null ; } }
你可能会觉得在else里面无法访问到value变量,其实在js内部会造成变量提升,这意味着我们可以在else里面访问到value变量,只是它未初始化,所以其变量值为undefined。实际解析时代码可能像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function getValue(condition) { var value; if (condition) { value = "blue"; // other code return value; } else { return null; } }
var会造成变量提升
const const除了具有let的块级作用域和不会变量提升外,还有就是它定义的是常量,在用const定义变量后,我们就不能修改它了,对变量的修改会默默的失败(在iojs中会抛出异常,在Chrome下会默默的失败)。例如:
1 2 3 4 const PI = 3.1415; console.log(PI); PI = 22; console.log(PI);
http://cookfront.github.io/2015/05/28/es6-let-const/