Javascript入门1.0
首先
是一个熟悉的段子
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>some test</title>
</head>
<body>
<div>
<a href=javascript:;>11</a>
</div>
<div>
<a href=#>22</a>
</div>
<div>
<a href=javascript:void(0);>33</a>
</div>
<script>
var a_list = document.getElementsByTagName('a');
for(var i = 0; i < 3; i++) {
a_list[i].innerHTML = i;
}
</script>
</body>
</html>
自豪的写了三种不同的不跳转的a,其实大概就是花式false
然后感觉..诶?我点让他点击弹出来点什么东西来,于是
var a_list = document.getElementsByTagName('a');
for(var i = 0; i < 3; i++) {
a_list[i].onclick = function() {
alert(i);
};
}
结果悲剧了,为什么都弹出3啊(哇,假装好奇的样子)
开始回忆
这个问题的话,没有记错的话,是因为这里的i是一个全局变量,ES5没有块作用域,不过有个函数作用域
所以当每个人被点的时候,onclick被调用的时候,i=3, 所以都会alert(3);
开始好像有过疑问,为什么不是a_list[0]
绑定onclick的时候就变成了
function() {
alert(0);
}
这样子的呢,hhhhhh~我也不知道
找到解决办法
以前用过的
使用ES6
这个办法我知道使用let
使用一个闭包
一直以来我就是用的这个var a_list = document.getElementsByTagName('a'); for(var i = 0; i < 3; i++) { a_list[i].onclick = (function(arg_i) { return function() { alert(arg_i); } })(i); }
当时感觉这种写法特别帅
别写错了.要return一个function的,别把alert写在立即执行的匿名函数里
剩下几种就是今天学到的了
把i存到每个对象里
var a_list = document.getElementsByTagName('a'); for(var i = 0; i < 3; i++) { a_list[i].arg = i; a_list[i].onclick = function() { alert(this.i); }; }
不够帅气,但很简单直观
匿名函数往外写了一层?
var a_list = document.getElementsByTagName('a'); for(var i = 0; i < 3; i++) { (function(arg) { a_list[i].onclick = function() { alert(arg); }; })(i); }
其实相当于把i变量绑定到匿名函数里作为一个局部变量(其实个人感觉传进来的参数和局部变量在很多地方都是相似的)了,相当于是利用了传说中的函数作用域
这次是真的用了一个局部变量
var a_list = document.getElementsByTagName('a'); for(var i = 0; i < 3; i++) { (function() { var arg = i; //这个arg虽然用了var但不是全局变量 a_list[i].onclick = function() { alert(arg); }; })(); }
好了皆大欢喜
另外,看到一句话
绝大多数的同步的地方改成异步都都可以用上述方法,只要将需要异步的部分(通常是从某一行开始到函数末尾)包含在闭包中,就可以进行异步处理了