javascript立即執(zhí)行函數(shù)和閉包

閉包

概念:當(dāng)內(nèi)部函數(shù)被保存到外部時(shí),將會(huì)生成閉包。閉包會(huì)導(dǎo)致原有作用域鏈
舉例分析:

function  a(){
    function b(){
        var bbb = 234;
        console.log(aaa);
    }
    var aaa = 123;
    return b;
}
var glob = 100;
var demo = a();
demo();
//a函數(shù)在執(zhí)行的時(shí)候,會(huì)生成自己的執(zhí)行期上下文AO對(duì)象,b函數(shù)是在
//a函數(shù)內(nèi)部定義的,所以b函數(shù)在定義的時(shí)候,形成的執(zhí)行期上下文隊(duì)像
//就會(huì)有a函數(shù)的AO對(duì)象,當(dāng)a函數(shù)執(zhí)行完畢的時(shí)候,內(nèi)部的變量會(huì)被當(dāng)作垃圾
//回收,此時(shí)a函數(shù)的執(zhí)行期上下文被銷毀,但a產(chǎn)生的AO對(duì)像并沒(méi)有被當(dāng)作垃圾回收,
//因?yàn)榇藭r(shí)b函數(shù)被保存出來(lái),然后javascript程序并沒(méi)有運(yùn)行完畢,
//b函數(shù)依然指向a函數(shù)的AO對(duì)象,b執(zhí)行的時(shí)候依然可以從a函數(shù)內(nèi)部拿值

閉包的應(yīng)用:

//1,實(shí)現(xiàn)累加器
function add(){
    var num = 100;
    function b (){
        num++;
        console.log(num);
    }
    return b;
}
var counter = add();
counter();//101
counter();//102
//b函數(shù)每次都是拿的add函數(shù)所產(chǎn)生的那個(gè)AO對(duì)象,所以每次都會(huì)加一
//2,可以做緩存
function eater(){
    var food = "";
    var obj = {
        eat:function (){
            console.log('i am eating'+food);
            food = "";
        },
        push:function (myFood){
            food = myFood;
        }
    }
    return obj;
}
var eater1 = eater();
eater1.push('banana');
eate1r.eat();
//3,私有化變量
function Father(surname,address){
  var money = 10000;
  this.xing = surname;
  this.address = address;
  this.howmuchmony = function (){
    console.log("我有多少錢:",money);
  }
}
var son = new Father("sun","杭州");
son.money;//訪問(wèn)不到
son.howmuchmony();//只有son提供了相應(yīng)的方法,你才能訪問(wèn)到

立即執(zhí)行函數(shù)

概念:執(zhí)行完立即被銷毀的函數(shù),javascript提供給我們的唯一可以執(zhí)行完手動(dòng)銷毀函數(shù)的方式。
實(shí)則是被當(dāng)作表達(dá)式被括號(hào)執(zhí)行了。此類函數(shù)沒(méi)有聲明,在一次執(zhí)行過(guò)后即釋放。適合做初始化工作。
假設(shè)全局有兩個(gè)函數(shù)a和b,這兩個(gè)函數(shù)除非等到j(luò)avascript執(zhí)行完,不然一直占用內(nèi)存空間得不到釋放。
形式1:( function () {}() );//w3c建議第一種
形式2:( function () {})();
其他的一些寫法:

 function test(){
    var a = 123;
 }();
//這種形式不能執(zhí)行,這種叫函數(shù)聲明,只有表達(dá)式才能被執(zhí)行符號(hào)執(zhí)行

var test = function (){
    console.log(5464);
}();
+ function test1(){
    console.log(8788);
}();
- function test2(){
    console.log(8788);
}();
! function test3(){
    console.log(8788);
}();
(function test() {
    console.log(89);
}());
//+,-,!會(huì)把函數(shù)聲明變成表達(dá)式,所以能被執(zhí)行,能被執(zhí)行符號(hào)執(zhí)行的表達(dá)式會(huì)自動(dòng)忽略函數(shù)名,
//此時(shí)test(),是undefined,這種寫就相當(dāng)于立即執(zhí)行函數(shù),執(zhí)行完被釋放,test寫了也沒(méi)意義。

下面看些題目

一、
function test4(a,b,c,d){
     console.log(a+b+c+d);
 }();//這樣程序會(huì)報(bào)錯(cuò)
function test4(a,b,c,d){
    console.log(a+b+c+d);
}(1,2,3,4);
//理論上不能執(zhí)行,這樣不會(huì)報(bào)錯(cuò),也不會(huì)執(zhí)行函數(shù),程序可以照常運(yùn)行
//因?yàn)?)如果當(dāng)成執(zhí)行符號(hào)就會(huì)報(bào)錯(cuò),系統(tǒng)是能不報(bào)錯(cuò)就不報(bào)錯(cuò),就會(huì)解釋成
// function test4(a,b,c,d){
//     console.log(a+b+c+d);
// }
//  (1,2,3,4);這樣的兩段代碼
//把(1,2,3,4);解釋成都好表達(dá)式
//test()還是可以運(yùn)行

二、
function test5(){
    var arr = [];
    for(var i=0;i<10;i++){
      ( function(j){

        arr[j] = function (){
            console.log(j);
        }
      }(i))//立即執(zhí)行函數(shù)里面有函數(shù)被返回,也是可以訪問(wèn)里面的變量,閉包的應(yīng)用
    }
    return arr;
}
var myArr = test5();
for(var i=0;i<myArr.length;i++){
    myArr[i]();//每次去訪問(wèn)i的時(shí)候,都是去不同的AO對(duì)象里面去找
}

三、
使用原生js,addEventListener,給每個(gè)li元素綁定一個(gè)click事件,輸出他們的順序
<ul>
        <li>a</li>
        <li>a</li>
        <li>a</li>
        <li>a</li>
 </ul>
function foo(){
    var liCollection = document.getElementsByTagName("li");
    for(var i=0;i<liCollection.length;i++){
        (function(j){
           liCollection[j].addEventListener("click",function(){
            console.log(j);
            })
        }(i))
        
    }
}
foo();

四、
寫一個(gè)方法,求一個(gè)字符串的字節(jié)長(zhǎng)度。(提示:字符串有一個(gè)方法charCodeAt();一個(gè)中文占兩個(gè)字節(jié),一個(gè)英文占一個(gè)字節(jié))
charCodeAt()方法可返回指定位置的字符串Unicode編碼。這個(gè)返回值是0-65535
之間的整數(shù)。當(dāng)返回值是<=255時(shí)為英文,當(dāng)返回值>255時(shí)為中文
// function retBytesLen(str){
//     var count = 0;
//     for(var i=0;i<str.length;i++){
//         if(str.charCodeAt(i)<=255){
//             count++;
//         }else{
//             count+=2;
//         }
//     }
//     return count;
// }
function retBytesLen(str){
    var len = str.length;
    var count = len;
    for(var i=0;i<len;i++){
        if(str.charCodeAt(i)>255){
            count++;
        }
    }
    return count;
}

五、
var f = (
        function f(){
            return "1";
        },
        function g(){
            return 2;
        }
    )();
  console.log(typeof f)  //number
    // var f = (
    //     function g(){
    //         return 2;
    //     }
    // )();簡(jiǎn)化候就是立即執(zhí)行函數(shù)

六、
var x = 1;
if(function f(){}){
    x+=typeof f;
}
console.log(x);
//括號(hào)會(huì)把函數(shù)變成表達(dá)式,變成表達(dá)式他就不是函數(shù)定義,就消失了
//沒(méi)定義的變量只有放在typeof 里面才不會(huì)報(bào)錯(cuò),返回undefined,
//typeof 返回字符串類型,
七、

     function Person(name,age,sex){
        var a = 0;
        this.name = name;
        this.age = age;
        this.sex = sex;
        function sss(){
            a++;
            console.log(a); 
        }
        this.say = sss;
     }
     var person1 = new Person();
     person1.say();//1
     person1.say();//2
     var person2 = new Person();
     person2.say();//1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容