JavaScript 之 面向對象 [ Function類型 ]

Function類型

描述

  • 在JavaScript中的全部函數都是Function類型的對象

定義函數的方式

函數聲明方式

function 函數名 () { 
    函數體 
}
/* 函數聲明方式定義函數 */
function fun() {
    console.log( '函數聲明方式...' );
}
fun();// 顯示 函數聲明方式...

字面量方式

var 函數名 = function () { 
    函數體 
}
/* 字面量方式定義函數 */
var fu = function () {
    console.log( '字面量方式...' );
}
fu();// 顯示 字面量方式...

構造函數方式

var 函數名 = new Function( 參數,函數體 )
  • 函數的參數和函數體,都以字符串形式填寫在括號中,以逗號分隔
  • 在使用構造函數建立一個Function類型的對象時,會獲得一個函數
/* 構造函數方式定義函數 */
var fn = new Function( 'can', 'console.log( can )' );
fn('構造函數方式...');// 顯示 構造函數方式...

判判定義的函數是否爲Function類型

/* 函數聲明方式 */
console.log( fun instanceof Function );// true
/* 字面量方式 */
console.log( fu instanceof Function );// true
/* 構造函數方式 */
console.log( fn instanceof Function );// true

apply()方法

  • 表示用於調用指定函數
  • 該方法接收兩個參數數組

    • 第一個 - this
    • 第二個 - 一個數組閉包

      • 該數組用於存儲指定函數的全部參數(實參)
/* 定義一個函數 */
function fun( can ) {
    console.log( can );
}
/* 根據函數語法正常調用函數 */
fun( '這是一個函數' );// 顯示 這是一個函數

/*
    根據Function對象提供的apply()方法進行函數調用
     * 參數 this 能夠先用 null 站位
 */
fun.apply( null, ['這仍是一個函數'] );// 顯示 這仍是一個函數

call()方法

  • 表示用於調用指定函數
  • 該方法接收兩個參數app

    • 第一個 - this
    • 第二個 - 函數的參數
      -需求多少參數,寫多少參數,使用逗號分隔
/* 定義一個函數 */
function fun( can, shu ) {
    console.log( can + shu );
}
/* 根據函數語法正常調用函數 */
fun( '這是一個函數', '...' );// 顯示 這是一個函數...

/*
    根據Function對象提供的call()方法進行函數調用
     * 參數 this 能夠先用 null 站位
 */
fun.call( null, '這仍是一個函數', '...' );// 顯示 這仍是一個函數...

bind()方法

  • 表示建立一個新的函數(稱爲綁定函數)
  • 該方法接收兩個參數函數

    • 第一個 - this
    • 第二個 - 函數的參數this

      • 需求多少參數,寫多少參數,使用逗號分隔
  • 該方法的返回值 - 返回一個新的函數code

    • 返回的新函數 - 是對指定函數進行復制獲得的
    • 兩個函數對函數體進行修改不會相互影響
/* 定義一個函數 */
function fun( can, shu ) {
    console.log( can + shu );
}
/* 根據函數語法正常調用函數 - 對參數進行修改 */
fun( '...', '這是一個函數' );// 顯示 這是一個函數...   修改後顯示 ...這是一個函數

/*
    根據Function對象提供的bind()方法進行函數調用
     * 參數 this 能夠先用 null 站位
     * 兩個函數之間不會有影響
 */
var fn = fun.bind( null, '這仍是一個函數', '...' );
fn();// 顯示 這仍是一個函數...

重載

  • 表示定義多個同名的函數,但每一個函數可接收的參數不一樣
  • 在調用時會進行判斷,函數會根據形參可接收的個數去匹配傳入實參個數相同的

注意

  • 在JavaScript的函數中不存在重載
  • 當函數同名時,最後一次定義的函數有效
/* 重載現象 */
function fn( a, b ){
    return a + b;
}
function fn( a, b, c ){
    return a + b + c;
}
function fn( a, b, c, d ){
    return a + b + c + d;
}
/* 重載的正常顯示 */
fn( 1, 2 );// 顯示 3
fn( 1, 2, 3 );// 顯示 6
fn( 1, 2, 3, 4 );// 顯示 10
/* JavaScript中的顯示結果 */
console.log( fn( 1, 2 ) );// 顯示 NaN
console.log( fn( 1, 2, 3 ) );// 顯示 NaN
console.log( fn( 1, 2, 3, 4 ) );// 顯示 10

arguments對象

  • 該對象能夠獲取當前指定函數中的因此參數(實參),並存儲到一個類數組中
  • 該對象只能在函數中使用
  • length屬性 - 表示函數中參數的個數
  • 該方法能夠模擬實現函數的重載
function fun(){
    /* 經過length屬性獲取函數參數的個數 */
    var add = arguments.length;
    /* 再經過條件語句進行判斷 */
    switch ( add ) {
        /* 根據參數的個數進行顯示 */
        case 2:
            /* 因爲arguments對象將獲取到的參數儲存到一個類數組中,可使用數組的方式進行提取 */
            return arguments[0] + arguments[1];
            break;
        case 3:
            return arguments[0] + arguments[1] + arguments[2];
            break;
        case 4:
            return arguments[0] + arguments[1] + arguments[2] + arguments[3];
            break;
    }
}
/* 能夠模擬出重載的效果 */
console.log( fun( 1, 2 ) );// 顯示 3
console.log( fun( 1, 2, 3 ) );// 顯示 6
console.log( fun( 1, 2, 3, 4 ) );// 顯示 10

遞歸

  • 表示在一個函數中,調用自身

注意

  • 若是不給遞歸設置一個出口,會出現相似於循環語句中的 死循環

解決

  • 經過在遞歸的過程當中不斷改變數據值
  • 在進行條件判斷來設置出口
  • 利用return語句的結束效果,結束遞歸

arguments對象的callee屬性

  • 該屬性表示當前正在執行的函數
function fun() {
    console.log( '啊哈哈' );
    /*
        調用自身函數 - 實現遞歸
         * 會出現相似於循環語句中的 死循環
     */
    fun();
}
fun();

/* 能夠設置一個循環出口 */
function fn( a ) {
    console.log( a );
    /* 經過條件判斷來設置出口 */
    if ( a >= 10 ) {
        /* 利用return語句的結束效果,結束遞歸 */
        return;
    }
    /* 在遞歸的過程當中不斷改變數據值 */
    fn( a + 1 );
}
/* 傳入一個數值用於條件判斷 */
fn( 0 );

/* 若是將遞歸函數賦值個一個變量,再將遞歸函數清空釋放,在去執行變量會出錯 */
function fu( b ) {
    console.log( b );
    if ( b >= 10 ) {
        return;
    }
    /*
        新函數(s)在執行時,內部的函數體,依然是舊函數(fu)的
        當執行到改變數據值時,調用的目標依舊是舊函數(fu)而沒有更改爲新函數(s)
        因此會報錯 - TypeError: fu is not a function

        能夠經過arguments對象的callee屬性去替換函數名
        arguments對象的callee屬性
         * 該屬性表示當前正在執行的函數
     */
    // fu( b + 1 );
    /* 修改後在執行就可正常顯示 */
    arguments.callee( b + 1 );
}
fu( 0 );
/* 將遞歸函數賦值個一個變量 */
var s = fu;
/* 將遞歸函數清空釋放 */
fu = null;
/* 使用函數方式執行變量 */
s( 0 );
/* 會報錯 */
console.log( s );// 顯示 fu is not a function

匿名函數

  • 表示定義一個沒有函數名的函數

匿名函數的用法

  • 將匿名函數做爲參數傳遞給其餘函數對象

    • 這種方法也能夠叫作 回調函數
  • 將匿名函數用於執行一次性任務遞歸

    • 這種方法也能夠叫作 自調函數
/* 建立一個匿名函數 */
function (){
    console.log( '啊哈哈' );
}

回調函數

  • 表示一個函數作爲參數傳入到另外一個函數中
/* 定義一個函數 - 該函數作爲另外一個函數的參數 */
var fn = function () {
    return 10;
}

/* 定義另外一個函數 */
var fun = function ( f ) {
    /* 傳進該函數體中的是一個函數,能夠直接調用 */
    return f();
}
/* 當前函數的參數爲另外一個函數 */
var s = fun( fn );
console.log( s );// 顯示 10

自調函數

  • 表示在定義函數後自行調用

用法

  • 第一種 - 兩個小括號ip

    • 第一個小括號 - 定義匿名函數
    • 第二個小括號 - 調用
/* 第一種方法 */
(function(){
    console.log( '啊哈哈' );
})();
  • 第二種 - 一個小括號中包含另外一個小括號作用域

    • 第一個小括號 - 定義匿名函數
    • 第二個小括號(被包含的) - 調用
/* 第二種方法 */
(function(){
    console.log( '呀吼吼' );
}());
  • 第三種 - 歎號 + 小括號

    • 歎號後寫匿名函數
    • 小括號 - 調用
/* 第三種方法 */
!function(){
    console.log( '哦哦哦' );
}();

做爲值的函數

  • 表示一個函數作爲另外一個函數的返回值
function fun() {
    var s = 10;
    return function () {
        return s;
    }
}
console.log( fun()() );// 顯示 10

做用域鏈

  • 表示函數做用域有權限訪問除自身內部的函數做用域以外的其餘做用域
  • 而且會把次特性傳遞個自身內部的函數做用域
var a = 100;// 全局變量
function fun1(){
    var b = 200;// fun1函數做用域的局部變量
    // 內部函數
    function fun2(){
        var c = 300;// fun2函數做用域的局部變量
        // 內部函數
        function fun3(){
            var d = 400;// fun3函數做用域的局部變量
            // 調用變量
            console.log(a);// 100
            console.log(b);// 200
            console.log(c);// 300
            console.log(d);// 400
        }
        fun3();
        // 調用變量
        // console.log(a);// 100
        // console.log(b);// 200
        // console.log(c);// 300
        // console.log(d);// d is not defined
    }
    fun2();
    // 調用變量
    // console.log(a);// 100
    // console.log(b);// 200
    // console.log(c);// c is not defined
    // console.log(d);// d is not defined
}
fun1();

閉包理論

  • 表示在全局做用域能夠訪問到函數做用域中的數據
  • 做用域的逆向操做(我的理解)
/* 定義一個全局變量但不賦值 */
var s;
function fun(){
    var v = 100;
    /* 在函數做用域中對全局變量進行賦值 */
    s = function(){
        console.log(v);
    }
    s();
}
fun();// 顯示函數體的內容 100
/* 訪問全局變量會獲得在函數做用域中數值 */
s();// 顯示全局變量的值 100
相關文章
相關標籤/搜索