标签:click name btn src 打印 cti 历史 add ++
事实上 var的设计可以看成是js语言设计上的一个错误,但是这种错误多半不能修复和已出,因为要前后兼容,大概2008年的时候,Brendan Eich就决定修复这个错误,于是他添加了一个新的关键词:let,我们可以将let看成更完美的 var,很多语言在它早期被设计的时候,基于当时历史的原因,他考虑不到以后可能面临的问题,所以很多语言都是有缺陷的,比如java,近几年一直在频繁的更新,一年更新一个版本甚至两三个版本,块级作用域
js中使用var来声明一个变量时,变量的作用域主要和函数的定义有关
针对其他快定义来说是没有作用域的,比如if/for,这在我们开发中往往会遇到一些问题
let和var都是用来定义变量的,但是let是有块级作用域的,var没有块级作用域,
那么什么是作用域?? 作用域其实完整叫法应该是变量作用域 ,就是变量在什么范围内是可用的,很多语言都是有块级作用域的,
没有块级作用域会引起的问题 if的块级
var fn;
if (true) {
var name = "kobe"
fn = function() {
console.log(name)
}
}
var name = "james"
fn()
本来你是想打印kobe的,结果你不知道什么时候在外面重新定义了下name,结果james替换了kobe
没有块级作用域会引起的问题 for的块级
var btns = document.getElementsByTagName("button");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
console.log(i)
})
}
函数里面的i一直是引用的外面的i 而外面的i是一直在改变的,点击第一个按钮的时候你其实希望打印的是0 ,但是在你点击按钮的时候,已经for循环已经结束了,i已经从0变到1变到2变到3变到4变到5了,
解决办法1(闭包)
为什么闭包可以解决,因为函数是一个作用域,函数里面的i一旦赋值之后,不会被改掉,ES6之前因为if和for都没有块级作用域,所以在很多时候,我们都必须借助于function的作用域来解决应用外面变量的问题
var btns = document.getElementsByTagName("button");
for (var i = 0; i < btns.length; i++) {
(function(i){
btns[i].addEventListener("click", function() {
console.log(i)
})
})(i)
}
解决办法2(let)
ES6中 let 可以使if 和 for都具有了块级作用域
var btns = document.getElementsByTagName("button");
for (let i = 0; i < btns.length; i++) {
(function(i){
btns[i].addEventListener("click", function() {
console.log(i)
})
})(i)
}
标签:click name btn src 打印 cti 历史 add ++
原文地址:https://blog.51cto.com/13550695/2463558