1. 程式人生 > >JavaScript的進階之路(二)函數簡介,變量、作用域和內存問題

JavaScript的進階之路(二)函數簡介,變量、作用域和內存問題

ret 優化 person get 簡介 web瀏覽器 都是 add 是把

<h3>ECMAScript中函數不存在函數簽名的概念,沒有重載</h3>
<h3>無需指定返回值,可以在任何時候返回任何值。未指定返回值的函數,返回的是一個特殊的undefined值</h3>

<script type="text/javascript">
            function sayHi(){
                console.log("Hi");
            };
            sayHi();
            function sayName(name,age){
                console.log(
"我是"+name+",我今年"+age+"歲了!"); }; sayName("吳瓊",18); function sum(num1,num2){ return num1+num2; alert("我不會被執行到!"); //位於return語句之後的任何代碼都不會執行。 } sum(1,2); function compare(n1,n2){ if(n1<n2){ console.log(n1
+"小於"+n2); }else if(n2<n1){ console.log(n2+"小於"+n1); }else{ console.log("他們倆相等!"); } } compare(2,2); </script>

<h1>基本類型和引用類型的值</h1>
<h3>在操作對象時,實際上是在操作對象的引用,而不是實際的對象。</h3>
<h3 class="red">基本類型具有動態的值,引用類型具有動態的屬性。</h3>
<h3 class="red">復制變量值:基礎類型是復制一個新值;引用類型是復制一個指針。</h3>
<h3 class="red">傳遞參數:可以把函數的參數當成一個局部變量。基本類型傳遞參數是復制值給一個局部變量,引用類型傳遞參數是復制一個地址給變量對象;</h3>
<h2 class="red">之前說到函數的參數是按值傳遞的,那麽復制的這個地址可以當做一個值嗎?答案:可以。為什麽?</h2>
<h3>檢測變量:typeof 操作符可以確定一個變量是字符串、數值、布爾值,還是undefined的最佳工具。檢測對象時,用instanceof操作符。</h3>

<h1>執行環境(也稱作用域)</h1>
<h3>每個環境都有一個與之關聯的變量對象。執行環境有2種:全局和局部(函數)。</h3>
<h3 class="red">作用域鏈的作用:保證 (對執行環境有權訪問的 )(所有變量和函數的) 有序訪問;</h3>
<h3>作用域鏈的前端始終都是所在環境的與之關聯的變量對象。在Web瀏覽器中,window對象始終是最頂端。</h3>
<h3>函數的參數也被當成變量來對待,訪問規則與執行環境中的其他變量相同。</h3>
<h2>延長作用域鏈</h2>
<h3>try{}catch(e){}語句的catch塊 和 with語句可以延長作用域鏈。</h3>
<h2>沒有塊級作用域:像if語句中聲明的變量和for語句中聲明的循環變量,在外部均可以訪問到;</h2>
<h3>在函數中的變量如果想在外部訪問,必須是全局變量(沒有var聲明的變量)。</h3>
<h3>在函數中的變量查找規則是從內環境到外環境。</h3>
<h1>垃圾收集:找出那些不在繼續使用的變量,然後釋放其占用的內存。常見的2個策略:標記清除和引用計數。</h1>
<h3>關於垃圾收集產生的性能問題:IE6默認值,IE7根據內存用量動態的修改值,性能比IE6大大提高。</h3>
<h3>關於管理內存:JavaScript分配給Web瀏覽器的可用內存量比分配給桌面應用程序的要少。</h3>
<h2 class="red">內存限制會影響網頁的性能:1、給變量分配的內存 2、調用棧以及在一個線程中同時執行的語句數量。</h2>
<h2 class="red">確保占用最少的內存可以讓頁面獲得更好的性能。而優化內存占用的最佳方式就是為執行中的代碼只保存必要的數據。</h2>
<h2 class="red">解除引用:將用不到的全局變量設置為null來釋放其引用。此時,並沒有釋放內存,只是讓值脫離了執行環境,下次垃圾回收時再釋放。</h2>

<script type="text/javascript">
            var a=1;
            var b=a;
            delete a;
            console.log(b); //a對b沒有任何影響
            var obj1=new Object();
            var obj3=new Object();    
            var obj2=obj1;
            obj1.name="吳瓊";
            console.log(obj2.name);
            obj2.name="張虹";
            console.log(obj1.name);
            console.log(obj3.name);
            var num = 1;
            function add(sum){
                sum+=10;
                console.log(sum);
            };
            add(num);  // 基本類型傳遞參數是把變量num的值復制給一個局部變量sum;
            console.log(num);  //變量的值並沒有改變
            function odd(obj){
                obj.name="吳瓊";
            }
            var person = new Object();
            odd(person);
            console.log(person.name); 
            
            function odd2(obj){
                obj.name="吳瓊";
                var obj = new Object();   //在函數內的變量引用的是一個局部對象,在函數執行完畢後會立即被銷毀;
                obj.name="張虹";
            };
            var person2=new Object();
            odd(person2);   //把person2傳遞給odd2()方法後,其name屬性的值被定義為“吳瓊”,如果是按引用傳遞的,則obj的name會被修改;
            console.log(person2.name);
            console.log(odd instanceof Function);
            //測試沒有塊級作用域
            if(true){
                var color = "red";
            }
            console.log(color);  // red//測試沒有塊級作用域
            for(var i=0;i<10;i++){
                //
            };
            console.log(i); //10 //測試沒有塊級作用域
            //函數中的變量在外部訪問
            var sum;
            function fn(num1,num2){
                sum = num1+num2;
            };
            fn(1,2);
            console.log(sum);  //如果函數內聲明var sum 則報錯sum is not defind
            //作用域鏈的查詢
            var col = "black";
            function getCol(){
                var col = "blue";  //從內到外查找  如果有這個聲明,則 blue
                return col;
            }
            console.log(getCol());  //blue
            getCol();  //執行方法後,函數內用var 聲明的變量依然為局部變量
            console.log(col);//black
        </script>

JavaScript的進階之路(二)函數簡介,變量、作用域和內存問題