<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## ## **聲明函數** ``` //申明普通函數 function fun(){}; fun()//執行普通函數 //函數表達式申明 var fun1=function(){}; fun1() //執行函數表達式申明 的函數 //使用Function構造函數 var fun2=new Function(); fun2()//函數表達式申明 ``` >每個 JavaScript 函數實際上都是一個`Function`對象。運行`(function(){}).constructor === Function // true`便可以得到這個結論 ## **立即執行函數申明** 直接這樣寫function foo(){}()解釋器會報錯 **IIFE**(立即調用函數表達式)函數的調用方式通常是將函數表達式、它的調用操作符、分組操作符放到一個括號內,來告訴解釋器這里有一個需要立即執行的函數。否則通常情況下,解析器遇到一個function關鍵字,都會把它當做是一個函數聲明,而不是函數表達式 ``` //此寫法前面最好加分號,否則他前面的執行體沒有結束符時就會報錯 ;( function foo(){ //... }() ) //此寫法前面最好加分號,否則他前面的執行體沒有結束符時就會報錯 ;( function foo(){ //... } ) () !function foo() { //... }() +function foo() { //... }() -function foo() { //... }() ~function foo() { //... }() ``` ## **立即執行的匿名函數** ``` //此寫法前面最好加分號,否則他前面的執行體沒有結束符時就會報錯 ;( function(){ console.log(11111); }() ) //此寫法前面最好加分號,否則他前面的執行體沒有結束符時就會報錯 ;( function() { console.log(11111); } ) () !function() { //... }() +function() { //... }() -function() { //... }() ~function() { //... }() ``` **call()與apply()** 這兩個方法都是函數對象的方法,需要通過函數對象來調用 當對函數調用call()和apply ()都會調用函數執行 ``` function demo(){} //下面三種方式效果一樣都是調用函數 demo();//以函數的形式調用 //以方法的形式調用 demo.apply(); demo.call(); ``` **解析器在調用函數時每次都會向函數內部傳遞進兩個隱含的參數** * 1、第一個隱含的參數就是this this指向的是一個對象,這個對象我們稱為函數執行的上下文對象 根據函數的調擁方式不同,this會指向不同的對象 1.以函數的形式調用時,this永遠都是Window 2.以方法的形式調用時,this就是調用方法傳遞的那個對象 ``` var obj={ name:"object", sayName:function(a,b){ console.log(this.name); console.log(a,b) } }; var obj2={ name:"object2", }; //call方法可以將實參在對象之后傳遞 //apply方法需要將實參統一放入數組中傳遞 obj.sayName();//object undefined undefined obj.sayName.apply();//空 undefined undefined obj.sayName.apply(obj2);//object2 obj.sayName.apply(obj2,[1,2]);//object2 1 2 obj.sayName.call(obj2,1,2);//object2 1 2 ``` * 2、第二個隱含參數是封裝實參的對象arguments arguments是一個類數組對象,它也可以通過索引來操作數據,也可以獲取長度 在調用函數時,我們所傳遞的實參都會在arguments中保存 arguments.length可以用來獲取實參的長度 它里邊有一個屬性叫做callee,這個屬性對應一個函數對象,就是當前正在指向的函數的對象 ``` function demo(){ console.log(this); console.log(arguments[0]); console.log(arguments.length); //console.log(arguments.callee==demo); //true } demo();//Window undefined 0 demo("a","b",true);//Window a 3 ``` **閉包:** ```html <button>按鈕1</button> <button>按鈕2</button> <button>按鈕3</button> <script type="text/javascript"> var btn=document.getElementsByTagName("button") for (var i = 0; i < btn.length; i++) { btn[i] } //上面循環一次就要計算一次長度,改成下面這種形式性能更好 for (var i = 0,len=btn.length; i < len; i++) { btn[i].onclick=function(){ console.log(i+1);//點擊哪個按鈕都全是4 } } //改成這樣 for (var i = 0,len=btn.length; i < len; i++) { btn[i].index=i btn[i].onclick=function(){ console.log(this.index+1); } } //或者以閉包形式 for (var i = 0,len=btn.length; i < len; i++) { (function(i){ btn[i].onclick=function(){ console.log(i+1); } })(i) } </script> ``` 如何產生閉包?當一個嵌套的內部(子)函數引用了嵌套的外部(父)函數的變星(函數)時,就產生了閉包 產生閉包的條件?:函數套內部函數引用了外部函數的數據(變量/函數) 函數定義執行完成 ``` //分別在var a=2;和var b=2;處打斷點 function fn1(){ var a=2;//斷點執行到此時由于函數提升此時已有閉包 function fn2(){ console.log(a) } fn2(); } fn1(); function fn3(){ var b=2;//斷點在此時無閉包 var fn4=function(){ console.log(b) } fn4(); } fn3(); ``` **閉包函數的常用使用場景** 1,將函數作為另一個函數的返回值 ``` //例子1:未達到引用了外部函數的數據的條件,所以沒有閉包 function fn1(){ function fn2(){} return fn2; } fn2(); //例子2:達到閉包的條件 function fn1(){ var a=2; function fn2(){ a++; console.log(a) } return fn2; } fn2(); //例子3:達到閉包的條件 function fn1(){ var a=2; function fn2(){ a++; console.log(a) } return fn2; } f=fn2();//函數的內容執行完即自動銷毀,但是fn2賦值給了f,系統就不會自動銷毀 f()//3 f()//4 f=null//死亡條件:成為垃圾對象 function fn1(){ var a=2; function fn2(){ a++; console.log(a) } return fn2; } fn2();//無值,函數的內容執行完即自動銷毀 ``` 2·將函數作為實參傳遞給另一個函數調用 1.使用函數內部的變量在函數執行完后,仍然存活在內存中(延長了局部變量的生命周期) 2·讓函數外部可以操作(讀寫)到函數內部的數據(變量/函數) 問題: 1·函數執行完后,函數內部聲明的局部變量是否還存在? 一般不會存在,只有存在于閉包中的變量才能存在 2.在函數外部能直接訪問函數內部的局部變量嗎? 不能,但可以通過閉包來操作它 閉包示例之定義js模塊: ``` function moudle(){ var msg="hello world!"; function fn1(){ return "fn1:"+msg; } function fn1(){ return "fn2:"+msg; } return { fn1:fn1, fn2:fn2 } } //優化 (function(){ var msg="hello world!"; function fn1(){ return "fn1:"+msg; } function fn1(){ return "fn2:"+msg; } window.moudle2 ={ fn1:fn1, fn2:fn2 } })() //進一步優化。使其成為可以壓縮的代碼 (function(w){ var msg="hello world!"; function fn1(){ return "fn1:"+msg; } function fn1(){ return "fn2:"+msg; } w.moudle2 ={ fn1:fn1, fn2:fn2 } })(window) ``` ``` //缺點函數執行完后,函數內的局部變量沒有釋放,占用內存時間會變長容易造成內存泄露 //解決:能不用閉包就不用 及時釋放 function fun1(){ var arr=new Array[1000]; function fn2(){ console.log(arr.length); } return fn2; } var f=fn1(); f(); ``` 面試題: ``` var name1="the window"; var obj1={ name1:"my object1" fn1:function(){ return function(){ return this.name1; } } } obj1.fn1()();//the window var name2="the window"; var obj2={ name1:"my object2" fn2:function(){ var that=this; return function(){ return that.name2; } } } obj2.fn2()();//my object2 function fun(n,o){ console.log(o); return { fun:function(m){ return fun(m,n); } } } var a=fun(0); a.fun(1) a.fun(2) a.fun(3) var b= fun(0).fun(1).fun(2).fun(3) var c=fun(0).fun(1); c.fun(2) c.fun(3) ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看