JS高級- OOP-ES5

1. OOP數組

面向對象三大特色: 封裝,繼承,多態瀏覽器

 封裝:ide

  問題: 構造函數可重用代碼和結構定義,但沒法節約內存函數

    爲何: 放在構造函數內的方法定義,每new一次,都會反覆建立副本——浪費內存this

  解決: 繼承prototype

 繼承:對象

  什麼是: 父對象的成員,子對象無需重複建立,就可直接使用繼承

  爲何: 代碼重用, 節約內存內存

  什麼時候: 只要發現多個子對象,但願擁有共同的方法定義時原型鏈

  如何: js中都是經過繼承原型對象來實現繼承關係

   原型對象: 集中存儲多個子對象,共有成員的父對象

   什麼時候: js中只要實現繼承,都要使用原型對象

   如何:

    建立: 不用本身建立。買一贈一!

     只要建立一個構造函數,都附贈一個原型對象

     構造函數的prototype屬性指向原型對象

    如何繼承: 不用本身繼承。

     new的第二步: 讓新對象自動繼承構造函數的原型對象

      本質: 設置新對象的__proto__指向父對象

        凡是從__proto__指出的引用,都是繼承關係

    咱們作什麼: 決定將那些方法集中添加到原型對象中

      構造函數中,再也不包含任何方法定義

    調用對象的方法時:

      如今子對象本地找方法,

      若是找不到,就延__proto__,向父元素查找

   

 內置對象的原型對象:

  內置對象: ES標準中規定的,瀏覽器廠商已經實現的對象

   11個:

    String  Number  Boolean ——包裝類型

    Array  Date  RegExp  Math

    Error

    Function  Object

    Global(瀏覽器中被window代替)

   其實能new的,都是構造函數

   每一個構造函數都有一個原型對象

   原型對象中保存着該類型的全部子對象共用的API

   問題: 舊瀏覽器不支持新的API

   解決: 在該類型的原型對象中添加自定義方法

     強調: 在方法內,可用this指代未來調用該方法的.前的對象

   捷徑: 在網上搜索: MDN 類型.prototype.方法名

     找Polyfill, 直接複製粘貼便可

 

  包裝類型: String  Number   Boolean

   什麼是: 專門保存原始類型的值,並提供操做原始類型值的API

   爲何: 原始類型的值自己什麼功能都沒有

   什麼時候: 只要用原始類型的值,打.訪問方法或屬性時

   如何: 不用本身用!

    好比: var n=345.678; n.toFixed(2);
          typeof n   number

          new Number(n).toFixed(2)  345.68

          //new Number釋放

        var str="hello"; str.replace("o","0");

          typeof str   string

          new String(str).replace("o","0");

          //new String釋放

 原型鏈(prototype chain):

  什麼是: 由多級父元素,逐級繼承,造成的鏈式結構

  保存着全部對象,以及對象的成員

  控制着對象成員的使用順序:

    先自有,再向父級找共用

   vs 做用域鏈:

    保存全部孤立的變量, 控制着變量的使用順序:

     先局部,後全局

  自有屬性 vs 共有屬性:

   自有屬性: 當前對象本地保存的屬性

   共有屬性: 原型鏈中父級對象中的屬性

   讀取屬性值: 子對象.屬性名

   修改屬性值: 自有屬性: 用子對象.屬性名=值

              共有屬性: 必須用父對象.屬性名=值

 鄙視: 判斷一個對象是數組, 共有幾種方法: 4種

  typeof: 只能區分原始類型和function

       不能進一步區分引用類型

  1. 判斷原型對象:

    //obj.__proto__==Array.prototype

    father.isPrototypeOf(child)

     判斷father是否是child的父對象

    判斷數組: Array.prototype.isPrototypeOf(obj)

  2. 判斷構造函數:

    //obj.constructor == Array

    child  instanceof  構造函數

     判斷child是不是構造函數new出的子對象

    判斷數組: obj  instanceof  Array

 

  問題: 不夠嚴格: 不但檢查直接父對象,並且檢查整個原型鏈

  解決: 驗證對象的class屬性

  3. 驗證對象的class屬性:

   每一個對象都有一個隱藏的class屬性(不能用.直接訪問)

   class屬性的值,在建立對象時就肯定了,用於保存類型名

   class屬性不隨後天繼承關係的改變而改變

   如何得到class屬性:

    惟一的辦法: 調用頂級父對象Object.prototype中的toString()

    問題: 每種內置類型的原型對象都重寫了頂級父對象中的toString(),已經再也不返回class屬性值

      全部子對象沒法調用到Object.prototype中的toString()

    解決: 搶!

     要搶的函數.call(對象)

      在執行時: 對象.要搶的函數()

    判斷對象是否是數組類型:

     Object.prototype.toString.call(obj)==="[object Array]"

     用obj去搶頂級父對象中的toString(),若是返回"[object Array]" 就說明是數組

  4. Array.isArray(obj)

 

 多態:

  什麼是: 同一個函數在不一樣狀況下表現出不一樣的狀態

  包括:

   1. 重載:

   2. 重寫(override):

    什麼是: 子對象定義了和父對象相同的成員

    爲何: 從父對象繼承來的東西,可能很差用

    什麼時候: 只要以爲從父對象繼承來的東西,很差用

    如何: 在子對象中定義和父對象重名的成員

 

自定義繼承關係: 3種:

 1. 僅修改一個對象的父對象:

   //child.__proto__=father

   Objext.setPrototypeOf(child,father)

 2. 批量修改全部子對象的父對象:

   構造函數.prototype=father

   時機: 在定義構造函數後,馬上更換

相關文章
相關標籤/搜索