在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ 如何理解閉包

如何理解閉包

1.使用var:

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

2.使用let

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

問題:在1中,循環(huán)內(nèi)被賦給數(shù)組a的函數(shù)內(nèi)部的console.log(i),里面的i指向的是全局的i,那a[i]的i豈不是也指向全局的i,那豈不是只有a[10]有值?

回答
編輯回答
囍槑

1、循環(huán)中的語句是立即執(zhí)行
2、每進(jìn)一次循環(huán),都會(huì)給數(shù)組第i項(xiàng)賦值
3、這里賦值的是個(gè)函數(shù),但函數(shù)并沒有執(zhí)行
所以循環(huán)完了是這樣的:

[
function(){console.log(i)},
function(){console.log(i)},
function(){console.log(i)},
function(){console.log(i)},
function(){console.log(i)},
function(){console.log(i)},
function(){console.log(i)}
]
//由于全局的i是10
//所以每一項(xiàng)打印都是10
2017年6月27日 13:24
編輯回答
執(zhí)念

不要為了學(xué)閉包而閉包, 考慮閉包能做什么... 我感覺
首先,不要相當(dāng)然的認(rèn)為 程序按你的想法運(yùn)行, 我感覺 計(jì)算機(jī) 算是一門嚴(yán)謹(jǐn)?shù)目茖W(xué)。
js 詞法作用域...
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = (function (i) {

       return function () {
            console.log(i);
          };

})(i)
}
a[6](); // 6

//

2017年8月16日 17:47
編輯回答
貓小柒

我從《你不了解的JS》總結(jié)了關(guān)于如何理解閉包:

  1. 某個(gè)函數(shù)擁有上級(jí)(或上多級(jí))作用域的引用, 就叫做閉包
  2. 當(dāng)函數(shù)記住并訪問其所在的詞法作用域, 即便它是在當(dāng)前詞法作用域之外執(zhí)行, 這就產(chǎn)生了閉包
  3. 閉包可以使得函數(shù)就訪問定義時(shí)的詞法作用域, 所以實(shí)際上,只要使用了回調(diào)函數(shù)就使用了閉包

配合一段經(jīng)典的面試代碼就很好理解其一:

function Timer () {
    let time = 1
    return function () {
        console.log(time ++)
    }
}

關(guān)于題主的問題,相關(guān)閉包,但主要不在“閉包”上,應(yīng)該是“var與let的作用域的問題”,只有當(dāng)你了解了閉包并且了解了var與let作用域的不同才能想通這兩個(gè)循環(huán)。

總結(jié)下JS的塊級(jí)作用域(偽塊級(jí)作用域):

  1. let
  2. try catch
  3. IIFE
  4. with(不推薦使用)
  5. 還有不。。記不清了
2017年8月16日 03:11
編輯回答
傻叼

支持樓上的看法,學(xué)閉包首先得理解這東西到底有什么用,說白了就是保存狀態(tài)。給你看個(gè)閉包實(shí)現(xiàn)復(fù)合數(shù)據(jù)結(jié)構(gòu)的例子把,源自SICP 原版是lisp寫的

// 閉包實(shí)現(xiàn)序?qū)?
let cons = (car,cdr) => (k)=> k === 1 ? car : cdr
let car = (cons) => cons(1)
let cdr = (cons) => cons(2)

// 建立一個(gè)序?qū)︽?var cons2 = cons('序?qū)?', '結(jié)束')
var cons1 = cons('序?qū)?', cons2)

console.log(cdr(cdr(cons1))) // 結(jié)束
2017年10月21日 10:50
編輯回答
茍活

謝邀。

額……你學(xué)擰巴了!

a[i]是一個(gè)立即取值,并不適用于閉包的概念。閉包是指一個(gè)函數(shù)在定義以后,被放到其他環(huán)境去執(zhí)行的情況。此時(shí)它的執(zhí)行環(huán)境仍然是定義它的那個(gè)環(huán)境,而不是執(zhí)行它的那個(gè)環(huán)境。

所以閉包是針對(duì)調(diào)用環(huán)境與執(zhí)行環(huán)境不同的函數(shù)來說的。其他情況可不能隨便套用。

2017年3月2日 06:43
編輯回答
心夠野

這個(gè)題還是不要扯到閉包上。應(yīng)該理解var與let的作用域的問題。
看下面的例子,你就知道了。

(function() {
  var varTest = 'test var OK.';
  let letTest = 'test let OK.';

  {
    var varTest = 'varTest changed.';
    let letTest = 'letTest changed.';
  }

  console.log(varTest); //varTest changed.
  console.log(letTest); //test let OK.
}());

再給你一個(gè)閉包的例子:

function a(){
  var n = 0;
  function inc() {
    n++;
    console.log(n);
  }
  inc();
  inc();
}
a(); //控制臺(tái)輸出1,再輸出2
2018年8月1日 12:18
編輯回答
陌離殤
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}

這里的a[i] 的意思相當(dāng)于循環(huán)給a數(shù)組添加十個(gè)匿名函數(shù)function () {console.log(i);}; 你可以打印一下a你就知道了 a[i]是已經(jīng)確立的了 至于執(zhí)行a[6]相當(dāng)于執(zhí)行數(shù)組中的第7個(gè)匿名函數(shù) 打印i 這時(shí)候因?yàn)槭褂玫氖莢ar 并不會(huì)產(chǎn)生塊作用域 所以i的取值等于最外層循環(huán)結(jié)束的i值就是10

2017年7月24日 03:14