05 - 閉包&&物件導向

weixin_34208283發表於2017-01-08

本文是針對剛學程式設計的小白,都是一些基礎知識,如果想了解更多深層一點的東西,歡迎移步本人部落格!!

部落格地址 點選跳轉


----------------- 補充動畫原理 ----------------------


三個取整函式

  • Math.ceil() 向上取整 天花板
  • Math.floor() 向下取整 地板
  • Math.round() 四捨五入

緩動動畫原理

  • 緩動動畫的原理:** 盒子本身的位置 + 步長 (不斷變化的,由大變小)**

  • 步長:begin = begin + (end - begin) / 緩動係數

基本的緩動動畫函式

// 緩動動畫
// 誰  目標
function buffer(obj, target) {  
    // 1. 清除定時器    
    clearInterval(obj.timer);    
    // 2. 設定定時器    
    obj.timer = setInterval(function () {        
           // 2.1 求出步長        
           var speed = (target - obj.offsetLeft) / 20;        
           console.log(speed);        
           speed = speed > 0 ? Math.ceil(speed): Math.floor(speed);        
           console.log(speed);        
           // 2.2 設定動畫        
           obj.style.left = obj.offsetLeft + speed + 'px';        
           obj.innerHTML = obj.offsetLeft;        
           // 2.3 清除定時器        
           if(obj.offsetLeft == target){           
                  clearInterval(obj.timer);        
            }    
     }, 20);
}

常見的 js訪問 CSS 屬性

  • 在開發中,訪問得到css 屬性,比較常用的有兩種:
    • 點語法
      box.style.width,box.style.height,box.style.top,box.style.left 得到帶有單位的屬性值,比如:200px; 但是,點語法存在一個很致命的問題,跟在style後面的屬性不能由外面傳入
var h = 'height'; 
box.style.h = 300 + 'px';
  • 下標語法
    利用 [] 訪問屬性 元素.style[“屬性”];
    這種語法的好處就是可以動態的傳遞引數作為屬性
    var h = 'height'; box.style[h] = 300 + 'px';

JS獲取CSS的樣式

在開發中,我們想要獲得css 的樣式,通常採用:box.style.top
box.style.backgorundColor等, 但這種方式只能得到 行內樣式,而平常用的最多的是頁內樣式或者外部樣式, 那我們如何解決這樣的問題?

  • 在IE和Opera瀏覽器
    obj.currentStyle
  • 其他W3C標準瀏覽器
    **window.getComputedStyle("元素", "偽類") **( 注意:兩個選項是必須的, 沒有偽類 用 **null **替代 )
  • 相容寫法
function getStyleAttr(obj, attr) {    
    if(obj.currentStyle){ // IE 和 opera        
         return obj.currentStyle[attr];    
    }else {        
         return window.getComputedStyle(obj, null)[attr]; 
    }
}

回撥函式

  • 在開發中,有很多操作是鏈式的,下一個操作接著上一個操作執行,那麼如何實現這樣的行為?** 回撥函式。**
    回撥函式什麼時候呼叫?
    --> 動畫結束的時候呼叫 ?
    --> 動畫什麼時候結束?
    ---> 定時器被清除的時候
    --> 定時器被清除時呼叫回撥函式

什麼是閉包

  • 閉包實際上是一種函式,所以閉包技術也是函式技術的一種;閉包能做的事情,函式幾乎都能做。

  • 閉包技術花式比較多,用法也比較靈活,一般開發人員在學習閉包的時候都會遇到瓶頸,主要是因為閉包技術的分界線並不明顯。幾乎無法用一個特點去區分

  • 當一個內部函式被其外部函式之外的變數引用時,就形成了一個閉包。

function A(){ 
   function B(){ 
       console.log("Hello XMG!");
   } 
   return B; 
} 
var b = A(); 
b();//Hello XMG!
  • 閉包的最大用處有兩個:
    一個是可以讀取函式內部的變數
    另一個就是讓這些變數的值始終保持在記憶體中。

封閉作用域

  • JavaScript的GC機制
    • 在javascript中,如果一個物件不再被引用,那麼這個物件就會被GC回收,否則這個物件一直會儲存在記憶體中。
  • 封閉作用域
    • 封閉作用域又稱值為封閉空間,還有一個暱稱叫小閉包,以及匿名函式自調。
    • 基本結構:
// 前面這兩種 企業開發中比較常用
(function(){})();
;(function(){})();
+(function(){})();
-(function(){})();
?(function(){})();
  • 技法最大目的: 全域性變數私有化
  • 技術優點:
    • 不汙染全域性空間!

    • 內部所有的臨時變數執行完畢都會釋放不佔記憶體。

    • 可以儲存全域性資料。

    • 更新複雜變數。

作用域鏈

  • 巢狀之間的函式會形成作用域鏈,每次對變數的訪問實際上都是對整條作用域鏈的遍歷查詢。先查詢最近的作用域,最後再查詢全域性作用域。如果在某個作用域找到了對量就會結束本次查詢過程。

  • 思考

    • 對於作用域全域性作用域查詢快,還是區域性作用域查詢快?
    • 區域性作用域查詢要遠遠大於全域性作用域查詢的速度。所以高階的程式設計一般是儘量避免全域性查詢。
    • 每次訪問都是對作用域鏈的一次遍歷查詢其中全域性作用域是最耗費時間的。
  • 解決方案:

    • 當前目標使用完以後,在退出作用域之前儲存這個目標,就可以在下次取到上一次的目標。
  • 補充:

變數的生命週期 任何一個變數在記憶體中都是一個引用,這個變數是有自己的生命週期。週期結束意味著被銷燬。 一個變數在它當前的作用域內被宣告那一刻相當於變數出生,整個當前作用域執行完畢並退出作用域相當於變數的壽命終止。

儲存作用域

  • 儲存作用域是一種更高階的閉包技術,如果函式巢狀函式,那麼內部的那個函式將形成作用域閉包。簡單的說,這種閉包能夠達到的好處就是讓指令能夠繫結一些全域性資料去執行;

  • 基本結構:

 var A=function(){
     return function(){};
 }
  • 優點:
    • 全域性資料隱藏化
    • 可以讓某個指令執行時候繫結一些隱藏的全域性資料在身上。
      一句話: 將資料繫結在指令上執行,讓指令不再依賴全域性資料。

物件導向

  • 物件是什麼?

    • 物件就是帶有屬性和方法的資料型別!
  • 任何一門高階語言都要物件導向,JavaScript則是基於原型的面嚮物件語言,因此,我們的思維要由程式導向轉向物件導向

3359912-ca023837ef0cab8c.png
**程式導向到物件導向**
  • 物件導向:

    • 物件導向裡面:類和物件

    • 類是物件的抽象,而物件是類的具體例項

    • 一切事物皆物件 JavaScript 萬物皆物件

  • 舉例

物件 女朋友
小白 你有物件了嗎? 泛指 女朋友
昨天陪你打LOL的那個女生是你物件嗎? 特指 某一個女朋友

在座的有喜歡吃香蕉的嗎?
你手中那根香蕉熟了嗎? 特指物件(具體的例項)

  • 物件導向的特性:

    • 抽象
      抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。

    • 封裝
      封裝是把過程和資料封閉起來,對資料的訪問只能通過開放的介面。

    • 繼承
      子類物件繼承使用父類的屬性和方法。

    • 多型
      多型是指兩個或多個屬於不同類的物件,對於同一個訊息(方法呼叫)作出不同響應的方式。

建構函式

所有的建構函式有一個特點:首字母大寫;

在js中我們可以理解為只要執行以後能夠返回新的物件的函式就是建構函式。

  • 建構函式技巧的最大目的:創造完全獨立的物件,互相之間不影響。

關鍵詞new

  • 將一個函式變成物件並返回
  • 在這個函式的內部將this指向函式本身。
  • new這個關鍵詞實際上能夠將任何函式直接變成一個物件。它只有在和建構函式配合的時候才有用,它相當於可以化簡建構函式自己創造物件和返回物件的步驟。

構造器(constructor) 和 原型屬性 (prototype)

  • 在任何一個物件中都有構造器和原型屬性,包括原生的物件,比如: Date, Array等;

  • constructor 返回對建立此物件的 建構函式的引用

  • prototype 讓我們有能力向物件新增屬性和方法

prototype它的作用就是建構函式的一個共享庫;在這個共享庫裡面儲存的所有資料將來都會被所有的新物件公用。 這樣大大降低了建立方法的成本。

  • 原型共享庫是誰使用的?

    • 建構函式使用原型庫,所有將來的物件共享這個原型庫。
    • 如果把方法都寫在建構函式的原型庫裡面,將來還可以通過原型繼續擴充。
  • 原型的工作原理?

    • 在網頁釋出以後,原型的工作會自動做以下兩件事情:
      第一:自動將原型庫中的所有內容都放在將來的物件身上;
      第二:如果共享庫中的內容發生變化會自動更新所有物件上的資料。
  • 注意:

    • 在物件導向的寫法當中,原型的共享庫裡面所有的方法中的this預設情況都會指向將來的物件。

    • 只有在兩個情況會發生變化,那麼這兩個情況一定要檢查作用域:
      第一:如果在事件的作用域中,this的指向會變成事件源。
      第二:如果在定時器的作用域中,this的指向會變成window。

    • 解決方案:備份指標

物件導向匹配案例

相關文章