鍍金池/ 問答/HTML5  HTML/ js閉包兩種寫法的區(qū)別

js閉包兩種寫法的區(qū)別

(function(j) {  // j = i
    setTimeout(function() {
        console.log(new Date, j);
    }, 1000);
})(i);
function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999

例子是隨便找的,這兩種寫法有什么區(qū)別和相同點呢?

回答
編輯回答
陌離殤

不太清楚你想了解什么
閉包就是一種特性,用在哪里的目的都是保存上一層的作用域內(nèi)的變量,沒有什么區(qū)別
硬要說區(qū)別只是你用他的特性來做不同的事情
在我的理解里,你直接在全局作用域下定義一個函數(shù),他也是一個閉包,因為他隨時都可以訪問到頂層作用域里的變量
再說一下你舉的例子
1.嚴格來講,這個例子應(yīng)該叫自執(zhí)行函數(shù)的應(yīng)用,跟閉包關(guān)系不太大,真正用到閉包的是setTimeout里面的這個函數(shù),他訪問了外層的參數(shù)j(注意當(dāng)執(zhí)行的時候j的值是i傳遞的),所以這個也常用在for循環(huán)內(nèi),網(wǎng)上例子很多。
2.這個就是很常見的閉包使用了,暴露給外界一個接口函數(shù),用來訪問內(nèi)部的n,可以用來模擬私有變量。

2017年1月22日 23:37
編輯回答
遲月

不太清楚你想問什么。
我猜你第一種是想處理下面的情況

// 隔1秒輸出5, 5, 5, 5, 5
for (var i = 0; i < 5; i++) {
    setTimeout(function () {
        // 直接使用i,因為i指向的內(nèi)存不變,輸出的時候i的值經(jīng)過循環(huán)變成了5,所以輸出5
        console.log(new Date(), i);
    }, i * 1000);
}

// 隔1秒輸出0, 1, 2, 3, 4
for (var i = 0; i < 5; i++) {
    (function (j) {
        // 使用閉包,瀏覽器給j分配新的內(nèi)存,不會隨i的變化而變化
        setTimeout(function () {
            console.log(new Date(), j);
        }, j * 1000);
    })(i);
}

第二個則是

function f1() {
    // 閉包防止數(shù)據(jù)被外部訪問
    var n = 999;
    function f2() {
        alert(n);
    }
    // 給f2一個add方法操作數(shù)據(jù)
    f2.add = function () {
        n++;
    }
    // 將f2暴露到外部
    return f2;
}

var result = f1();
result();   // 999
result.add();
result();   // 1000
result.n;   // undefined,無法獲取到變量n
2018年1月21日 02:06
編輯回答
巫婆

第一種常用語for循環(huán)中
因為js中只有函數(shù)內(nèi)有獨立作用域
for循環(huán)的i是全局變量 因為setTimeout延時執(zhí)行調(diào)用的時候i值早已循環(huán)到4所以取到的都是4
通過自執(zhí)行函數(shù)傳入?yún)?shù)形成局部變量,獲取的之后獲取的局部作用域的i

for(var i=0;i<5;i++){
    setTimeout(function(j) {
        console.log(new Date, j);
    }, 1000, i);//setTimeout第三個參數(shù)之后都是回調(diào)的參數(shù)
}

第二種獲取函數(shù)內(nèi)局部變量
常用兩種:
通過返回值

function f1() {
    var n = 999;
    function f2() {
        alert(n);
    }
    return f2;
}
var result1 = f1();
result1(); // 999

通過回調(diào)參數(shù)

function f2(fn) {
    var n = 999;
    fn(n);
}
f2(function(n) {
    alert(n)//999
});
2018年8月19日 06:22