2019web前端javascript--入门级理解作用域,闭包

写在前面:因为还没开始工作,可能有的部分有错,希望大家能指点出来,这是我看渡一的视频总结的笔记,所有的示例都来自视频,我算是一个搬运工了吧哈哈哈,视频讲的很好,强烈推荐大家去看一看ヾ(◍°∇°◍)ノ゙

作用域

外面的看不了里面的

例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 + ’ ');
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值