0x07

Summer Training Day 8.

IFE Task 15
异步,作用域与闭包

第二周的第一天.


IFE Task.


Task 15.



;

1
2
3
4
5
innerText//除去html标签外的内容.
split//split("",num)方法用于把一个字符串分割成字符串数组.左参数为分割标准,右参数为长度(可选).
childnodes//我们平时用document.getElementById("")获取的是元素节点,非文本节点,childnodes获取的即是元素节点的子节点(包括文本).
nodeValue//获取节点值
push//push方法在数组末尾添加一个或多个元素,并返回新长度(注意是长度数值而非返回新数组).

1
2
3
4
5
getData();//获取
sort();//排序
render();//显示
btnhandle();//绑定按钮
init();//执行

最后加一句防止按钮重复点击:

1
if(resort.innerText == "")


异步、作用域与闭包.


执行环境与作用域

1.执行环境(execution context,简称环境),每个环境都有与之对应的一个变量对象(variable object),包含在环境中定义的所有变量和函数。全局执行环境,是最外围的执行环境,在Web中被认为是windows对象。某个执行环境中的代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁,但在全局执行环境的直到应用程序退出才会被销毁。
2.每个函数都有自己的执行环境,当执行流进入一个函数,函数的环境会被推入一个环境栈中,执行完之后栈将其环境弹出,把控制权交还给之前的执行环境。
3.当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。其前端始终是当前执行的代码所在环境的变量对象。如果是函数,则其活动对象(activation object)为变量对象。活动对象最开始时只包含argument对象(此对象在全局是不存在的),全局执行环境的变量始终是作用域链的最后一个对象。
(摘自JavaScript高级程序设计)

闭包

定义:闭包是指有权访问另一个函数作用域中的变量的函数。
在函数内部创建另一个函数就是一种创建闭包。

攻略↓
Excuse me?这个前端88面试在搞事!
汤姆大叔的博客:”深入理解JavaScript系列(16):闭包(Closures)”


所以,不只是setTimeout的问题.

1
2
3
4
5
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
} //输出5个5

1
2
3
4
5
6
7
8
9
10
11
var data = [];
for (var k = 0; k < 3; k++) {
data[k] = function () {
alert(k);
};
}
data[0](); // 3, 而不是0
data[1](); // 3, 而不是1
data[2](); // 3, 而不是2
//上下文共用一个[[scope]]属性,故k改变

解决方法:

1
2
3
4
5
6
7
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i);
}//在匿名函数外部加闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//也可以在匿名函数内部return里边加闭包
//@汤姆大叔 版本
var data = [];
for (var k = 0; k < 3; k++) {
data[k] = (function _helper(x) {
return function () {
alert(x);
};
})(k); // 传入"k"值
}
// 现在结果是正确的了
data[0](); // 0
data[1](); // 1
data[2](); // 2

其实归根结底是函数声明但没有执行的问题.



以上.