写在前面:因为还没开始工作,可能有的部分有错,希望大家能指点出来,这是我看渡一的视频总结的笔记,所有的示例都来自视频,我算是一个搬运工了吧哈哈哈,视频讲的很好,强烈推荐大家去看一看ヾ(◍°∇°◍)ノ゙
作用域
外面的看不了里面的
例1.
function a() {
function b() {
var b = 234;
}
var a =123;
b();
}
var glob = 100;
a();
(1)函数a定义时,产生[[scope]],存了GO
(2)函数a执行时,生成自己的执行上下文aAO,把aAO放在scope chain的最顶端,即:
[[scpoe]]->scope chain
0:aAO
↓
1:GO
函数a查找变量时依据函数a的scope chain自上而下查找(其他同理)
0:aAO:b:function(),a:123
1:GO:a:function(),glob:100
(3)在函数a的执行过程中产生了b的定义
(4)函数b开始定义,产生了b[[scope]],b是在aAO,GO的环境中出生的(即b拿了a的劳动成果)
b 定义时 scope chain->0:aAO,1:GO
(5)函数b 执行时 scope chain->
0:bAO,1:aAO,2:GO
bAO:b:234
问题:
1.函数b执行时的aAO和函数a执行时的aAO是同一个吗
是的,是引用的
2.函数执行完销毁自己的执行上下文
1)
函数b执行完时,销毁自己的执行上下文bAO,恢复到被定义状态,等待下一次被执行
2)
函数b执行完了,函数a也执行完了
,函数a也销毁了自己的执行上下文aAO
aAO:b:function(),a:123
aAO还包含了b函数,相当于b函数整个消失了
3)
当a函数再次执行时又会再产生一个新的执行上下文aAO,相当于重新定义了b函数,全新的b函数出生
若a函数不执行的话,b函数永远不可能被定义
闭包
解决外面的看不了里面的问题
例1.错误版本
//---想在数组里添加10个函数,并把数组返回--
0. function test(){
1. var arr =[];
2. for(var i = 0 ; i < 10 ; i ++ ){
3. arr [i] = function () {
4. document.write( i + ' ');
5. }
6. }
7. return arr;
8. }
9. console.log(myArr);
10. var myArr = test();
//---输出myArr数组里的每一个---
11. for (var j = 0 ; j < 10 ; j ++){
12. myArr[j]();
13. }
输出结果:10 10 10 10 10 10 10 10 10 10
(1) arr的i和function()里的i不是同步的,function()在这里是一个引用值!,并不执行。
3.这是一个赋值过程,相当于arr[i]=函数引用
这10个函数共用一个执行上下文
3. arr [i] = function () {
4. document.write( i + ' ');
5. }
(2)是test函数的返回值,把十个函数返回到外部
7. return arr;
(3)myArr相当于新的数组,因为(1)往arr[]里添加了10个函数
10. var myArr = test();
(4)test()执行完后,i已经变为10了,
在12.myArrj;这一步访问4. document.write( i + ’ ');才会找i是什么,但是这个时候i已经变为10了
11. for (var j = 0 ; j < 10 ; j ++){
12. myArr[j]();
13. }
每一个myArr[j] ()都和test()形成闭包,用的testAO
注:
1.有的函数不在定义时执行
2.for循环在不满足条件时停止执行
3.函数在定义时不需要看里面的内容,他不执行,在执行时依据他的作用域链查找变量
例2.正确闭包–典型
function test() {
var arr =[];
for (var i = 0; i < 10 ; i ++){
(function (j) {
arr[j] = function () {
document.write( j + ' ');
}
}(i));
}
return arr;
}
var myArr = test();
//console.log(myArr);{}
for (var j = 0 ; j < 10 ; j ++){
myArr[j]();
输出结果:0 1 2 3 4 5 6 7 8 9
(1)myArr调用的是
function () {
document.write( j + ' ');
}*!/
}
(2)
(function (j) {
arr[j] = function () {
document.write( j + ' ');
}
}(i));
1)
function () {document.write( j + ’ ');
}
这个函数在查找j的时候,看的是function(j)里的j,是一一对应的,而上一个的是一对十(这一步是关键)
2)
function(){},执行上下文是function(j)
3)
即使function(j)被销毁了,function(){}也拿着function(j)()里的j
arr[j] = function () {}把函数存入arr[]里
4)什么时候执行test()
应该也是myArr[j]();
5)
立即执行函数是读到他就执行,在for循环时就被执行了
立即执行函数执行完只是把引用的藏起来了让别人找不到
6)
myArr调用的是function () {
document.write( j + ’ ');
}