JS面向對象之原型鏈

JS 面向對象之原型鏈

對象的原型鏈

  1. 只要是對象就有原型
  2. 原型也是對象
  3. 只要是對象就有原型, 而且原型也是對象, 所以只要定義了一個對象, 那麼就能夠找到他的原型, 如此反覆, 就能夠構成一個對象的序列, 這個結構就被成爲原型鏈
  4. 原型鏈到哪裏是一個頭?
  5. 一個默認的原型鏈結構是什麼樣子的?
  6. 原型鏈結構對已知語法結構有什麼修正?

原型鏈的結構

  1. 原型鏈繼承就是利用就是修改原型鏈結構( 增長、刪除、修改節點中的成員 ), 從而讓實例對象可使用整個原型鏈中的全部成員( 屬性和方法 )
  2. 使用原型鏈繼承必須知足屬性搜索原則

屬性搜索原則

  1. 所謂的屬性搜索原則, 就是對象在訪問屬性與方法的時候, 首先在當前對象中查找
  2. 若是當前對象中存儲在屬性或方法, 中止查找, 直接使用該屬性與方法
  3. 若是對象沒有改爲員, 那麼再其原型對象中查找
  4. 若是原型對象含有該成員, 那麼中止查找, 直接使用
  5. 若是原型尚未, 就到原型的原型中查找
  6. 如此往復, 直到直到 Object.prototype 尚未, 那麼就返回 undefind.
  7. 若是是調用方法就包錯, 該 xxxx 不是一個函數

原型鏈結構圖

  1. 構造函數 對象原型鏈結構圖
function Person (){};
    var p = new Person();

  1. {} 對象原型鏈結構圖
    數組

  2. [] 數組原型鏈結構圖
    瀏覽器

  3. Object.prototype 對應的構造函數
    app

  4. div 對應的構造函數
  5. div -> DivTag.prototype( 就是 o ) -> Object.prototype -> nulldom

var o = {
    appendTo: function ( dom ) {
    }
};
function DivTag() {}
DivTag.prototype = o;

var div = new DivTag();

函數的構造函數 Function

在 js 中 使用 Function 能夠實例化函數對象. 也就是說在 js 中函數與普通對象同樣, 也是一個對象類型( 很是特殊 )函數

  1. 函數是對象, 就可使用對象的動態特性
  2. 函數是對象, 就有構造函數建立函數
  3. 函數是函數, 能夠建立其餘對象(函數的構造函數也是函數)
  4. 函數是惟一能夠限定變量做用域的結構

函數是 Function 的實例

new Function( arg0, arg1, arg2, ..., argN, body );
  1. Function 中的參數所有是字符串
  2. 該構造函數的做用是將 參數連接起來組成函數
  • 若是參數只有一個, 那麼表示函數體
  • 若是參數有多個, 那麼最後一個參數表示新函數體, 前面的全部參數表示新函數的參數
  • 若是沒有參數, 表示建立一個空函數

建立一個打印一句話的函數

// 傳統的
    function foo () {
        console.log( '你好' );
    }
    // Function
    var func = new Function( 'console.log( "你好" );' );
    // 功能上, 這裏 foo 與 func 等價

建立一個空函數

// 傳統
    function foo () {}
    // Function
    var func = new Function();

傳入函數內一個數字, 打印該數字

// 傳統
    function foo ( num ) {
        console.log( num );
    }
    // Function
    var func = new Function ( "num" ,"console.log( num );" );
    func();

利用 Function 建立一個函數, 要求傳入兩個數字, 打印其和

var func = new Function( 'num1', 'num2', 'console.log( num1 + num2 );' );

練習: 利用 Function 建立一個函數, 要求容許函數調用時傳入任意個數參數, 而且函數返回這些數字中最大的數字.
練習: 利用 Function 建立一個求三個數中最大數的函數.prototype

// 傳統
    function foo ( a, b, c ) {
        var res = a > b ? a : b;
        res = res > c ? res : c;
        return res;
    }
    // Function
    var func = new Function( 'a', 'b', 'c', 'var res = a > b ? a : b;res = res > c ? res : c;return res;' )

解決代碼太長的辦法:設計

  1. 利用 加法 鏈接字符串
var func = new Function( 'a', 'b', 'c',
            'var res = a > b ? a : b;' +
            'res = res > c ? res : c;' +
            'return res;' );
  1. 利用字符串特性( 剛學 )
function foo ( a, b, c ) {
        var res = a > b ? a : b;
        res = res > c ? res : c;
        return res;
    }
    var func = new Function( 'a', 'b', 'c', 'return foo( a, b, c );' );
  1. ES6 的語法( 少瀏覽器實現 )
    • 使用 鍵盤左上角的 左單引號 表示可換行字符串的界定符
  2. (最終)利用 DOM 的特性完成該方法

arguments 對象

arguments 是一個僞數組對象. 它表示在函數調用的過程當中傳入的全部參數的集合.
在函數調用過程當中沒有規定參數的個數與類型, 所以函數調用就具備靈活的特性, 那麼爲了方便使用,
在 每個函數調用的過程當中, 函數代碼體內有一個默認的對象 arguments, 它存儲着實際傳入的全部參數.3d

js 中函數並無規定必須如何傳參code

  1. 定義函數的時候不寫參數, 同樣能夠調用時傳遞參數
  2. 定義的時候寫了參數, 調用的時候能夠不傳參
  3. 定義的時候寫了一參數, 調用的時候能夠隨意的傳遞多個而參數

在代碼設計中, 若是須要函數帶有任意個參數的時候, 通常就不帶任何參數, 全部的 參數利用 arguments 來獲取.
通常的函數定義語法, 能夠寫成:對象

function foo ( /* ... */ ) {
    }

利用 Function 建立一個函數, 要求容許函數調用時傳入任意個數參數, 而且函數返回這些數字中最大的數字.

function foo ( ) {
        // 全部的參數都在 arguments 中. 將其當作數組使用
        // 問題而已轉換成在有一個數組中求最大值
        var args = arguments;
        var max = args[ 0 ];
        for ( var i = 1; i < args.length; i++ ) {
            if ( max < args[ i ] ) {
                max = args[ i ];
            }
        }
        return max;
    }

練習: 利用 Function 寫一個函數, 要求傳入任意個數字 求和

函數的原型鏈結構

任意的一個函數, 都是至關於 Function 的實例. 相似於 {} 與 new Object() 的關係

function foo () {};
    // 告訴解釋器, 有一個對象叫 foo, 它是一個函數
    // 至關於 new Function() 獲得一個 函數對象
  1. 函數有 __proto__ 屬性
  2. 函數的構造函數是 Function
  3. 函數應該繼承自 Function.prototype
  4. Fucntion.prototype 繼承自 Object.protoype
  5. 構造函數有prototype, 實例對象纔有__proto__指向原型, 構造函數的原型纔有 constructor 指向構造函數

intanceof

array instanceof Array 判斷 構造函數 Array 的原型 是否在 實例對象 array 的原型鏈存在

相關文章
相關標籤/搜索