首頁  >  文章  >  web前端  >  對於JavaScript中的函數重載的說明

對於JavaScript中的函數重載的說明

不言
不言原創
2018-07-13 16:38:411562瀏覽

這篇文章主要介紹了關於JavaScript中的函數重載的說明,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

##說明

#JavaScript 中沒有真正意義上的函數重載。

函數重載

函數名稱相同,函數的參數清單不同(包括參數數量和參數類型),根據參數的不同去執行不同的運算。

我們舉個例子看看

function overload(a){
    console.log('一个参数')
}

function overload(a,b){
    console.log('两个参数')
}

// 在支持重载的编程语言中,比如 java
overload(1);         //一个参数
overload(1,2);    //两个参数


// 在 JavaScript 中
overload(1);         //两个参数
overload(1,2);    //两个参数
在JavaScript中,同一個作用域,出現兩個名字一樣的函數,後面的會覆蓋前面的,所以JavaScript 沒有真正意義的重載。

但有各種方法,能在 JavaScript 中模擬實現重載的效果。

先看第一種辦法,透過arguments 物件實現

arguments 對象,是函數內部的一個類別數組對象,它裡面保存著呼叫函數時,傳遞給函數的所有參數。

function overload () {
  if (arguments.length === 1) {
    console.log('一个参数')
  }
  if (arguments.length === 2) {
    console.log('两个参数')
  }
}

overload(1);      //一个参数
overload(1, 2);  //两个参数
這個例子非常簡單,就是透過判斷 arguments 物件的 length 屬性來決定有幾個參數,然後執行什麼操作。

但是參數少的情況下,還好,如果參數多一些,if 判斷就需要寫好多,就麻煩了。

所以,我們再來看一個經典的例子

在看這個例子之前,我們先來看一個需求,我們有一個 users 對象,users 對象的values 屬性中存一些名字。
一個名字由兩個部分組成,空格左邊的是 first-name ,空格右邊的是 last-name,像下面這樣。

var users = {
  values: ["Dean Edwards", "Alex Russell", "Dean Tom"]
};
我們要在users 物件中加入一個find 方法,

當不傳任何參數時, 傳回整個

users .values;   當傳一個參數時,就把first-name 跟這個參數相符的元素回傳;    
當傳兩個參數時,則將first-name 和last-name 都符合的回傳。

這個需求中 find方法 需要根據參數的個數不同而執行不同的操作,下來我們透過一個 addMethod 函數,來在 users 物件中加入這個 find 方法。

function addMethod (object, name, fn) {
  // 先把原来的object[name] 方法,保存在old中
  var old = object[name];

  // 重新定义 object[name] 方法
  object[name] = function () {
    // 如果函数需要的参数 和 实际传入的参数 的个数相同,就直接调用fn
    if (fn.length === arguments.length) {
      return fn.apply(this, arguments);

      // 如果不相同,判断old 是不是函数,
      // 如果是就调用old,也就是刚才保存的 object[name] 方法
    } else if (typeof old === "function") {
      return old.apply(this, arguments);
    }
  }
}
addMethod 函數,它接收3個參數         

第一個:要綁定方法的對象,    
第二個:綁定的方法名稱,      
#第三個:需要#第二個:綁定的方法名稱,      
#第三個:需要#第二個:綁定的方法名稱,      

#第三個:需要#第二個:綁定的方法名稱,      

#第三個:需要#第二個:綁定的方法名稱,      

#第三個:需要#第二個:綁定的方法名稱,      

#1綁定的方法

這個addMethod 函數在判斷參數個數的時候,除了用arguments 對象,還用了函數的length 屬性。 函數的 length 屬性,傳回的是函數定義時形參的個數。

簡單說函數的length 是,函數需要幾個參數,而

arguments.length

是呼叫函數時,真的給了函數幾個參數

function fn (a, b) {
  console.log(arguments.length)
}
console.log(fn.length);  // 2
fn('a');    // 1

下來我們來使用這個addMethod 函數

// 不传参数时,返回整个values数组
function find0 () {
  return this.values;
}
// 传一个参数时,返回firstName匹配的数组元素
function find1 (firstName) {
  var ret = [];
  for (var i = 0; i <code>addMethod 函數是利用了閉包的特性,透過變數old 將每個函數連接了起來,讓所有的函數都留在記憶體中。 </code>每呼叫一次 addMethod 函數,就會產生一個 old,形成一個閉包。 <p>我們可以透過 <img src="https://img.php.cn//upload/image/139/643/301/1531471079834608.jpg" title="1531471079834608.jpg" alt="對於JavaScript中的函數重載的說明">console.dir(users.find)</p> ,把 find 方法印到控制台看看。 <p></p><p></p><h3>上面這個例子是 jQuery 之父John Resig  寫的,他在他的部落格和他寫的書《secrets of the JavaScript ninja》第一版都有提到過,在書中的第4章也有講解Function overloading,文中的addMethod 函數就是書中的例子4.15,有興趣的朋友可以去看看。 </h3><blockquote>上面的例子,本質都是在判斷參數的個數,根據不同的個數,執行不同的操作,而下來舉的例子是透過判斷參數的類型,來執行不同的操作。 </blockquote><p>我們來看看 jQuery 中的 css( ) 方法。 <code></code>css( ) 方法傳回或設定符合的元素的一個或多個樣式屬性。 </p><p><img src="https://img.php.cn//upload/image/776/481/734/1531471070297469.png" title="1531471070297469.png" alt="對於JavaScript中的函數重載的說明">css(name|pro|[,val|fn])</p>  <p><br></p><p></p>我們可以看到css( ) 方法,有5種參數情況,其中3種是一個參數,另外兩種是兩個參數。 <p>而在只有一個參數的情況下,如果參數類型是字串或陣列就是取得屬性值,而如果參數是對象,就是設定屬性值。 </p><p>jQuery 的 css( ) 方法就是透過判斷參數的類型,來決定要執行什麼運算。 </p><blockquote>我們來看看jQuery 3.3.1中的原始碼</blockquote><pre class="brush:php;toolbar:false">// name 表示属性名
// value 表示属性值
css: function( name, value ) {
    return access( this, function( elem, name, value ) {
        var styles, len,
            map = {},
            i = 0;

        // 判断属性名是不是数组
        // 是数组就遍历,调用jQuery.css 方法传入每个属性名,获取样式
        if ( Array.isArray( name ) ) {
            styles = getStyles( elem );
            len = name.length;

            for ( ; i  1 );
}

css( ) 方法依賴三個方法:

1、jQuery.access( ) 方法,這個方法可以取得或設置,一個或多個屬性值

###jQuery.access( ) 方法裡有這樣的程式碼###
// 设置多个属性值
// 如果属性名(key)的类型是 object,就遍历这个对象
// 遍历一次就调用一次 access()方法,并传入这次的属性名和属性值
if ( jQuery.type( key ) === "object" ) {
    chainable = true;
    for ( i in key ) {
        jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
    }

// 设置一个值
} else if ( value !== undefined ) {
    ......
}
###也就是這個方法,在幫css( ) 方法判斷第一個參數是字串還是物件的。 ###
2、jQuery.style( ) 方法:在DOM節點上讀取或設定樣式屬性

#在css( )方法中,如果有傳第二個參數,也就是有要設定的屬性值時,那就會呼叫jQuery.style( ) 方法設定樣式

3、jQuery.css( ) :在DOM元素上讀取DOM樣式值

這裡的jQuery.css( )  是透過jQuery.extend( ) 新增的方法,而我們最開始提到的css( )方法,是透過jQuery.fn.extend( ) 新增的方法,他們不是同一個方法。

jQuery.extend( )與jQuery.fn.extend( )的差異

jQuery.extend( )是為jQuery類別新增類別方法(靜態方法),需要透過jQuery類別來呼叫(直接使用$.xxx 呼叫);

jQuery.fn.extend( )是為jQuery類別新增成員數(實例方法),所有jQuery實例都可以直接呼叫(需要使用$() .xxx 調用)。

重載的好處

重載其實是把多個功能相近的函數合併為一個函數,重複利用了函數名稱。
假如jQuery中的css( )方法不使用重載,那麼就要有5個不同的函數,來完成功能,那我們就需要記住5個不同的函數名,和各個函數相對應的參數的個數和類型,顯然就麻煩多了。

總結

雖然JavaScript 沒有真正意義上的重載,但重載的效果在JavaScript中卻非常常見,例如陣列的splice( )方法,一個參數可以刪除,兩個參數可以刪除一部分,三個參數可以刪除完了,再新增元素。
再例如parseInt( )方法,傳入一個參數,就判斷是用十六進位解析,還是用十進位解析,如果傳入兩個參數,就用第二個參數作為數字的基數,來進行解析。

文中提到的實現重載效果的方法,本質都是對參數進行判斷,不管是判斷參數個數,還是判斷參數類型,都是根據參數的不同,來決定執行什麼操作的。

雖然,重載能為我們帶來許多的便利,但是也不能濫用,不要把一些根本不相關的函數合為一個函數,那樣並沒有什麼意義。

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

對於js的事件冒泡和事件捕獲的分析

關於Ajax如何實作跨域訪問的問題介紹

以上是對於JavaScript中的函數重載的說明的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn