国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript函數(shù)重載

testHs / 1968人閱讀

摘要:譯者按之父巧妙地利用了閉包,實(shí)現(xiàn)了函數(shù)重載。在一個(gè)業(yè)余項(xiàng)目中,我寫(xiě)了一個(gè)簡(jiǎn)單的函數(shù),用于實(shí)現(xiàn)函數(shù)重載。而所謂函數(shù)重載,就是函數(shù)名稱一樣,但是輸入輸出不一樣。

譯者按: jQuery之父John Resig巧妙地利用了閉包,實(shí)現(xiàn)了JavaScript函數(shù)重載

原文: JavaScript Method Overloading

譯者: Fundebug

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權(quán)歸原作者所有,翻譯僅用于學(xué)習(xí)。

在一個(gè)業(yè)余項(xiàng)目中,我寫(xiě)了一個(gè)簡(jiǎn)單的addMethod函數(shù),用于實(shí)現(xiàn)函數(shù)重載(Method Overloading)。而所謂函數(shù)重載,就是函數(shù)名稱一樣,但是輸入輸出不一樣。或者說(shuō),允許某個(gè)函數(shù)有各種不同輸入,根據(jù)不同的輸入,調(diào)用不同的函數(shù),然后返回不同的結(jié)果。

addMethod函數(shù)如下:

// addMethod - By John Resig (MIT Licensed)
function addMethod(object, name, fn){
    var old = object[ name ];
    object[ name ] = function(){
        if ( fn.length == arguments.length )
            return fn.apply( this, arguments );
        else if ( typeof old == "function" )
            return old.apply( this, arguments );
    };
}

所謂addMethod函數(shù),簡(jiǎn)單的理解,就是給某個(gè)object,添加一個(gè)指定name的函數(shù)fn。它利用了閉包,可以通過(guò)old變量將先后綁定的函數(shù)鏈接起來(lái)。

你可以這樣使用addMethod函數(shù),將find函數(shù)直接添加到每個(gè)對(duì)象實(shí)例:

function Users(){
  addMethod(this, "find", function(){
    // Find all users...
  });
  addMethod(this, "find", function(name){
    // Find a user by name
  });
  addMethod(this, "find", function(first, last){
    // Find a user by first and last name
  });
}

你也可以將find函數(shù)添加到對(duì)象的prototype,這樣所有對(duì)象實(shí)例將共享find函數(shù):

function Users(){
    addMethod(Users.prototype, "find", function(){
      // Find all users...
    });
    addMethod(Users.prototype, "find", function(name){
      // Find a user by name
    });
    addMethod(Users.prototype, "find", function(first, last){
      // Find a user by first and last name
    });
}

users對(duì)象的find方法成功實(shí)現(xiàn)了重載,可以根據(jù)不同的輸入調(diào)用不同的函數(shù):

var users = new Users();
users.find(); // Finds all
users.find("John"); // Finds users by name
users.find("John", "Resig"); // Finds users by first and last name
users.find("John", "E", "Resig"); // Does nothing

這種方法有一些明顯的缺陷:

重載只能處理輸入?yún)?shù)個(gè)數(shù)不同的情況,它不能區(qū)分參數(shù)的類型、名稱等其他要素。(ECMAScript 4計(jì)劃支持這一特性,稱作Multimethods,然而該版本已被放棄)。

重載過(guò)的函數(shù)將會(huì)有一些額外的負(fù)載,對(duì)于性能要求比較高的應(yīng)用,使用這個(gè)方法要慎重考慮。

addMethod函數(shù)的秘訣之一在于fn.length。或許很多人并不清楚,所有函數(shù)都有一個(gè)length屬性,它的值等于定義函數(shù)時(shí)的參數(shù)個(gè)數(shù)。比如,當(dāng)你定義的函數(shù)只有1個(gè)參數(shù)時(shí),其length屬性為1:

(function(foo){}).length == 1

我做了一下測(cè)試,發(fā)現(xiàn)這個(gè)實(shí)現(xiàn)函數(shù)重載的方法適用于所有瀏覽器,如果有問(wèn)題的話請(qǐng)與我聯(lián)系。

如果你擔(dān)心只綁定單個(gè)函數(shù)時(shí)的性能問(wèn)題,你可以使用如下addMethod函數(shù):

// addMethod - By John Resig (MIT Licensed)
function addMethod(object, name, fn){
    var old = object[ name ];
    if ( old )
        object[ name ] = function(){
            if ( fn.length == arguments.length )
                return fn.apply( this, arguments );
            else if ( typeof old == "function" )
                return old.apply( this, arguments );
        };
    else
        object[ name ] = fn;
}

這樣綁定第一個(gè)函數(shù)時(shí),將不會(huì)有額外的操作,既簡(jiǎn)單又快速。當(dāng)綁定更多函數(shù)時(shí),則與原addMethod函數(shù)一樣,會(huì)有額外的性能損失。

這樣做還有一個(gè)額外的好處:對(duì)于那些參數(shù)個(gè)數(shù)不符合要求的函數(shù)調(diào)用,將統(tǒng)一又第一個(gè)綁定的函數(shù)處理。這時(shí)調(diào)用find方法的輸出如下:

var users = new Users();
users.find(); // Finds all
users.find("John"); // Finds users by name
users.find("John", "Resig"); // Finds users by first and last name
users.find("John", "E", "Resig"); // Finds all

本文介紹的方法不能改變世界,但是它很代碼量很少、很簡(jiǎn)單,巧妙地使用了JavaScript的特性。因此,我在我的書(shū)《Secrets of the JavaScript Ninja》也介紹了這個(gè)方法。

完整示例

根據(jù)原文介紹的方法,譯者實(shí)現(xiàn)了一個(gè)完整的示例代碼:

function addMethod(object, name, fn)
{
    var old = object[name];
    object[name] = function()
    {
        if (fn.length == arguments.length)
            return fn.apply(this, arguments);
        else if (typeof old == "function")
            return old.apply(this, arguments);
    };
}


// 不傳參數(shù)時(shí),返回所有name
function find0()
{  
    return this.names;
}


// 傳一個(gè)參數(shù)時(shí),返回firstName匹配的name
function find1(firstName)
{  
    var result = [];  
    for (var i = 0; i < this.names.length; i++)
    {    
        if (this.names[i].indexOf(firstName) === 0)
        {      
            result.push(this.names[i]);    
        }  
    }  
    return result;
}


// 傳兩個(gè)參數(shù)時(shí),返回firstName和lastName都匹配的name
function find2(firstName, lastName)
{ 
    var result = [];  
    for (var i = 0; i < this.names.length; i++)
    {    
        if (this.names[i] === (firstName + " " + lastName))
        {      
            result.push(this.names[i]);    
        }  
    }  
    return result;
}


function Users()
{
    addMethod(Users.prototype, "find", find0);
    addMethod(Users.prototype, "find", find1);
    addMethod(Users.prototype, "find", find2);
}


var users = new Users();
users.names = ["John Resig", "John Russell", "Dean Tom"];


console.log(users.find()); // 輸出[ "John Resig", "John Russell", "Dean Tom" ]
console.log(users.find("John")); // 輸出[ "John Resig", "John Russell" ]
console.log(users.find("John", "Resig")); // 輸出[ "John Resig" ]
console.log(users.find("John", "E", "Resig")); // 輸出undefined

憑直覺(jué),函數(shù)重載可以通過(guò)if…else或者switch實(shí)現(xiàn),這就不去管它了。jQuery之父John Resig提出了一個(gè)非常巧(bian)妙(tai)的方法,利用了閉包。

從效果上來(lái)說(shuō),users對(duì)象的find方法允許3種不同的輸入: 0個(gè)參數(shù)時(shí),返回所有人名;1個(gè)參數(shù)時(shí),根據(jù)firstName查找人名并返回;2個(gè)參數(shù)時(shí),根據(jù)完整的名稱查找人名并返回。

難點(diǎn)在于,users.find事實(shí)上只能綁定一個(gè)函數(shù),那它為何可以處理3種不同的輸入呢?它不可能同時(shí)綁定3個(gè)函數(shù)find0,find1find2啊!這里的關(guān)鍵在于old屬性。

addMethod函數(shù)的調(diào)用順序可知,users.find最終綁定的是find2函數(shù)。然而,在綁定find2時(shí),oldfind1;同理,綁定find1時(shí),oldfind0。3個(gè)函數(shù)find0,find1find2就這樣通過(guò)閉包鏈接起來(lái)了。

根據(jù)addMethod的邏輯,當(dāng)fn.lengtharguments.length不匹配時(shí),就會(huì)去調(diào)用old,直到匹配為止。

關(guān)于Fundebug

Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java實(shí)時(shí)BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計(jì)處理了7億+錯(cuò)誤事件,得到了Google、360、金山軟件、百姓網(wǎng)等眾多知名用戶的認(rèn)可。歡迎免費(fèi)試用!

版權(quán)聲明

轉(zhuǎn)載時(shí)請(qǐng)注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/07/24/javascript_metho_overloading/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/84507.html

相關(guān)文章

  • JavaScript中的函數(shù)重載(Function overloading)

    摘要:說(shuō)明中沒(méi)有真正意義上的函數(shù)重載。先看第一種辦法,通過(guò)對(duì)象來(lái)實(shí)現(xiàn)對(duì)象,是函數(shù)內(nèi)部的一個(gè)類數(shù)組對(duì)象,它里面保存著調(diào)用函數(shù)時(shí),傳遞給函數(shù)的所有參數(shù)。 說(shuō)明 JavaScript 中沒(méi)有真正意義上的函數(shù)重載。 函數(shù)重載 函數(shù)名相同,函數(shù)的參數(shù)列表不同(包括參數(shù)個(gè)數(shù)和參數(shù)類型),根據(jù)參數(shù)的不同去執(zhí)行不同的操作。 我們舉個(gè)例子看看 function overload(a){ conso...

    inapt 評(píng)論0 收藏0
  • JavaScript函數(shù)重載

    摘要:實(shí)現(xiàn)函數(shù)重載函數(shù)重載,是等編程語(yǔ)言中具有的一項(xiàng)特性,這項(xiàng)特性允許創(chuàng)建數(shù)項(xiàng)名稱相同但輸入輸出類型或個(gè)數(shù)不同的子程序,它可以簡(jiǎn)單地稱為一個(gè)單獨(dú)功能可以執(zhí)行多項(xiàng)任務(wù)的能力。其它在中加入了類型,它自帶函數(shù)重載。 JavaScript實(shí)現(xiàn)函數(shù)重載 函數(shù)重載(function overloading),是 Ada、C++、C#、D、Java等編程語(yǔ)言中具有的一項(xiàng)特性,這項(xiàng)特性允許創(chuàng)建數(shù)項(xiàng)名稱相同...

    SnaiLiu 評(píng)論0 收藏0
  • 重名就會(huì)被覆蓋?那JavaScript中是如何實(shí)現(xiàn)重載的呢?

    摘要:但是我們知道中是沒(méi)有重載的為什么沒(méi)重載不是的特性也會(huì)有的嗎,因?yàn)楹竺娑x的函數(shù)會(huì)覆蓋前面的同名函數(shù),但是重載那么好用,我們想在實(shí)現(xiàn)函數(shù)重載該怎么辦呢今天就來(lái)給大家講講在里面實(shí)現(xiàn)函數(shù)重載的兩個(gè)思路。這就是閉包的核心作用。 大家都知道,所謂重載,就是一組相同的函數(shù)名,有不同個(gè)數(shù)的參數(shù),在使用時(shí)調(diào)用一個(gè)函數(shù)名,傳入不同參數(shù),根據(jù)你的參數(shù)個(gè)數(shù),來(lái)決定使用不同的函數(shù)!重載這個(gè)在JAVA這些經(jīng)典的...

    mozillazg 評(píng)論0 收藏0
  • JavaScript實(shí)現(xiàn)函數(shù)重載

    摘要:我們知道,函數(shù)可以隨意傳遞任意數(shù)量任意類型的參數(shù),那么它有沒(méi)有重載呢答案是有的,下面我們通過(guò)種方法來(lái)實(shí)現(xiàn)的函數(shù)重載。因此,每次調(diào)用,都會(huì)有一個(gè)執(zhí)行環(huán)境保存著當(dāng)時(shí)的和,所以在調(diào)用的時(shí)候可以找到當(dāng)時(shí)注入的,實(shí)現(xiàn)函數(shù)重載。 概念 重載是指函數(shù)或者方法有相同的名稱,但是參數(shù)個(gè)數(shù)或類型不相同的情形,這樣的同名不同參的函數(shù)或者方法之間,互相稱之為重載函數(shù)或方法。 我們知道,JavaScript函數(shù)...

    QLQ 評(píng)論0 收藏0
  • JavaScript之模擬函數(shù)重載

    摘要:背景高級(jí)程序設(shè)計(jì)中提及,不支持函數(shù)重載。若出現(xiàn)函數(shù)名稱相同情況下,后者覆蓋前者,故此不會(huì)出現(xiàn)重載的情況。維基百科場(chǎng)景例如,一個(gè)工廠有著數(shù)量級(jí)的員工,期望通過(guò)姓名找到某一員工或某類員工,使用同一個(gè)方法通過(guò)透?jìng)鲄?shù)個(gè)數(shù)去查找員工。 背景 ???????《JavaScript高級(jí)程序設(shè)計(jì)》中提及,JavaScript 不支持函數(shù)重載。若出現(xiàn)函數(shù)名稱相同情況下,后者覆蓋前者,故此不會(huì)出現(xiàn)重載...

    chenjiang3 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<