這篇文章主要介紹了關於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 都符合的回傳。
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中文網!
相關推薦:
以上是對於JavaScript中的函數重載的說明的詳細內容。更多資訊請關注PHP中文網其他相關文章!