作用域和作用域鏈

1. *****作用域和作用域鏈

2. *****閉包


1. *****作用域和作用域鏈

   作用域scope: 

     什麼是: 一個變量的使用範圍——使用

                 本質上作用域是一個對象——存儲

                     作用域中的變量都是對象的成員

     程序/函數的執行過程: 

        1. 開始執行程序前:

            創建ECS(執行環境棧): 

                依次保存每個調用的函數的執行環境

            在ECS中壓入第一個全局執行環境(全局EC)

            創建window對象,全局EC引用window對象

            window就是全局作用域對象

        2. 開始執行程序:

            所有全局變量都保存在全局作用域對象window中

        3. 定義函數時:

            在全局添加函數名變量

            創建函數對象封裝函數定義

            函數名變量引用函數對象

            函數對象中有一個scope屬性,引用回創建函數時的作用域對象。通常都是window。

        4. 調用函數時:

            在ECS中壓入一個新的EC

            爲本次函數調用創建專門的活動對象(AO)

            在AO中創建所有函數定義中規定的局部變量

            其實AO就是函數作用域對象

                 所有局部變量都是AO的成員

            新的EC引用活動對象AO

            AO的parent指向window

            變量的使用順序: 

               先用AO(函數作用域)中的局部變量

               如果AO中沒有,纔去window(全局作用域)中找

        5. 函數調用後:

            本次函數調用的EC出棧

                導致函數作用域對象AO釋放

                       導致局部變量一同釋放

   作用域鏈(scope chain): 由多個作用域對象連續引用形成的鏈式結構。

      順序: 先函數作用域對象AO->全局作用域對象window

      所有的變量都保存在作用域鏈上的對象中

          局部變量都保存在函數作用域對象AO中

          全局變量都保存在全局作用域對象window中

      控制了: 變量的使用順序

        先用AO(函數作用域)中的局部變量

               如果AO中沒有,纔去window(全局作用域)中找


   閉包: 

     什麼是: 即重用變量,又防止變量被污染的一種機制

     爲什麼: 全局變量: 優: 可重用     缺: 易被全局污染

                 局部變量: 優: 不會被污染    缺: 不可重用

     何時: 即重用變量,又防止變量被污染

     如何: 3步: 

        1. 用外層函數包裹住受保護的變量和操作變量的內層函數

        2. 外層函數將內層函數返回到外部,被外部的變量保存

        3. 通過外部變量調用內層函數,訪問受保護的變量

     缺: 1. 佔用更多內存: 外層函數的AO

          2. 容易造成內存泄漏

     三特點: 1. 函數嵌套:

                  2. 外層函數包含一個受保護的局部變量

                 3. 外層函數將內層函數對象返回


1. *****面向對象OOP: 

   什麼是: 程序中都是先用對象來定義數據和功能,再按照邏輯的需要,訪問對象中的數據和功能。

   爲什麼: 和現實中人的想法非常接近。

   什麼是對象: 內存中同時存儲多個數據和功能的存儲空間

              描述現實中一個具體事物的屬性和功能的程序結構

                     事物的屬性,會成爲對象中的屬性

                     事物的功能,會成爲對象中的方法

   何時: 今後開始寫程序前,都要先用對象,描述好要操作的事物的屬性和功能,再按需使用對象的功能,訪問對象的屬性

   如何: 面向對象三大特點: 封裝,繼承,多態

      封裝: 將一個具體事物的屬性和功能集中定義在一個對象中

      創建自定義對象: ——封裝   3種: 

         1. 使用對象直接量: 

              var obj={

                  屬性名: 屬性值,

                         ... : ... ,

                  方法名: function(){... this.屬性名 ...},

                         ... : ... ,

              }

          強調: 對象自己的方法,要訪問自己的屬性,必須用this.屬性名.

           this->正在調用函數的當前對象自己


       2. 使用new: 2步:  

          var obj=new Object(); //創建一個空對象

          //向空對象中添加屬性和方法

          obj.屬性名=屬性值;

          obj.方法名=function(){...this.屬性名...};

          

     對象的本質: js中一切對象的底層都是關聯數組

                        每個屬性/方法都是關聯數組中的元素

                        屬性名/方法名是key,屬性值/函數對象是value


      問題: 一次只能創建一個對象

       3. 解決: 用構造函數: 

          什麼是構造函數: 專門描述一類對象統一結構的函數

          何時: 今後只要反覆創建多個相同結構的對象時,都要先定義構造函數

          爲什麼: 複用對象的結構代碼

          如何: 2步: 

            1. 定義構造函數

                function 類型名(屬性參數列表){

                     this.屬性名=屬性參數值;

                               ...=...;

                     this.方法名=function(){ ... this.屬性名 ...  }

                }

            2. 用new調用構造函數,創建並裝修新對象

                var obj=new 類型名(屬性值列表);

                     創建一個指定“類型”的對象

                     用new調用指定"類型"的構造函數來創建對象

              new: 4件事: 

                1. 創建新的空對象

                2. 讓新對象繼承構造函數的原型對象

                3. 用新對象去調用構造函數

                      向新對象中添加構造函數規定的屬性

                      將屬性參數的值,保存到新對象的新屬性中

                      向新對象中添加構造函數規定的方法

                4. 將新對象的地址保存在變量


      按需訪問對象的屬性,調用對象的方法:  

         訪問對象的屬性: obj.屬性名   用法和普通的變量完全一樣

                屬性就是保存在對象中的一個變量

         調用對象的方法: obj.方法名() 用法和普通的函數完全一樣

            強調: 方法中的this,默認指.前的對象


      構造函數的問題: 只能複用代碼,不能節約內存


      繼承: 父對象的成員,子對象不用重複創建,也可直接使用

      爲什麼: 即節約內存,又代碼重用

      何時: 只要一類子對象,需要相同的屬性或功能時,都要將相同的屬性和功能僅在父對象中定義一次即可

      如何: 

        原型對象: 集中存儲同一類型的子對象所需的所有共有屬性和方法的父對象














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章