函數(shù)重載和類(lèi)型檢查
其它面向?qū)ο蟮恼Z(yǔ)言(比如Java)的一種共有的特性是“重載”函數(shù)的能力:傳給它們不同數(shù)目或類(lèi)型的參數(shù),函數(shù)將執(zhí)行不同操作。雖然這種能力在JavaScript中不是直接可用的,一些工具的提供使得這種探求完全成為可能。 在JavaScript的每一個(gè)函數(shù)里存在一個(gè)上下文相關(guān)的名為arguments的變量,它的行為類(lèi)似于一個(gè)偽數(shù)組,包含了傳給函數(shù)的所有參數(shù)。參數(shù)不是一真正的數(shù)組(意味著你不能修改它,或者調(diào)用push()方法增加新的項(xiàng)),但是你可以以數(shù)組的形式訪問(wèn)它,而且它也的確有一個(gè)length屬性。程序2-5中有兩個(gè)示例。
程序2-5. JavaScript中函數(shù)重載的兩個(gè)示例
//一個(gè)簡(jiǎn)單的用來(lái)發(fā)送消息的函數(shù) function sendMessage( msg, obj ) { //如果同時(shí)提供了一個(gè)消息和一個(gè)對(duì)象 if ( arguments.length == 2 ) //就將消息發(fā)給該對(duì)象 obj.handleMsg( msg );
//否則,剛假定只有消息被提供 else //于是顯示該消息 alert( msg ); }
//調(diào)用函數(shù),帶一個(gè)參數(shù) – 用警告框顯示消息 sendMessage( "Hello, World!" );
//或者,我們也可以傳入我們自己的對(duì)象用 //一種不同方式來(lái)顯示信息 sendMessage( "How are you?", { handleMsg: function( msg ) { alert( "This is a custom message: " + msg ); } });
//一個(gè)使用任意數(shù)目參數(shù)創(chuàng)建一個(gè)數(shù)組的函數(shù) function makeArray() { //臨時(shí)數(shù)組 var arr = []; //遍歷提交的每一個(gè)參數(shù) for ( var i = 0; i < arguments.length; i++ ) { arr.push( arguments[i] ); } //返回結(jié)果數(shù)組 return arr; }
另外,存在另一種斷定傳遞給一個(gè)函數(shù)的參數(shù)數(shù)目的方法。這種特殊的方法多用了一點(diǎn)點(diǎn)技巧:我們利用了傳遞過(guò)來(lái)的任何參數(shù)值不可能為undefined這一事實(shí)。程序2-6展示一了個(gè)簡(jiǎn)單的函數(shù)用來(lái)顯示一條錯(cuò)誤消息,如果沒(méi)有傳給它,則提供一條缺省消息。
程序2-6: 顯示錯(cuò)誤消息和缺省消息
function displayError( msg ) { //檢查確保msg不是undefined if ( typeof msg == 'undefined' ) { //如果是,則設(shè)置缺省消息 msg = "An error occurred."; }
//顯示消息 alert( msg ); }
typeof語(yǔ)句的使用引入了類(lèi)型檢查。因?yàn)镴avaScript(目前)是一種動(dòng)態(tài)類(lèi)型語(yǔ)言,使得這個(gè)話題格外有用而重要的話題。有許多種方法檢查變量的類(lèi)型;我們將探究?jī)煞N特別有用的。 第一種檢查對(duì)象類(lèi)型的方式是使用顯式的typeof操作符。這種有用的方法給我們一個(gè)字符串名稱(chēng),代表變量?jī)?nèi)容的類(lèi)型。這將是一種完美的方案,除非變量的類(lèi)型或者數(shù)組或自定義的對(duì)象如user(這時(shí)它總返回"ojbect",導(dǎo)致各種對(duì)象難以區(qū)分)。 這種方法的示例見(jiàn)程序2-7
程序2-7. 使用typeof決定對(duì)象類(lèi)型的示例
//檢查我們的數(shù)字是否其實(shí)是一個(gè)字符串 if ( typeof num == "string" ) //如果是,則將它解析成數(shù)字 num = parseInt( num );
//檢查我們的數(shù)組是否其實(shí)是一個(gè)字符串 if ( typeof arr == "string" ) //如果是,則用逗號(hào)分割該字符串,構(gòu)造出一個(gè)數(shù)組 arr = arr.split(",");
檢查對(duì)象類(lèi)型的第二種方式是參考所有JavaScript對(duì)象所共有的一個(gè)稱(chēng)為constructor的屬性。該屬性是對(duì)一個(gè)最初用來(lái)構(gòu)造此對(duì)象的函數(shù)的引用。該方法的示例見(jiàn)程序2-8。
程序2-8. 使用constructor屬性決定對(duì)象類(lèi)型的示例
//檢查我們的數(shù)字是否其實(shí)是一個(gè)字符串 if ( num.constructor == String ) //如果是,則將它解析成數(shù)字 num = parseInt( num );
//檢查我們的字符串是否其實(shí)是一個(gè)數(shù)組 if ( str.constructor == Array ) //如果是,則用逗號(hào)連接該數(shù)組,得到一個(gè)字符串 str = str.join(',');
表2-1顯示了對(duì)不同類(lèi)型對(duì)象分別使用我所介紹的兩種方法進(jìn)行類(lèi)型檢查的結(jié)果。表格的第一列顯示了我們?cè)噲D找到其類(lèi)型的對(duì)象。每二列是運(yùn)行typeof Variable(Variable為第一列所示的值)。此列中的所有結(jié)果都是字符串。最后,第三列顯示了對(duì)第一列包含的對(duì)象運(yùn)行Variable.constructor所得的結(jié)果。些列中的所有結(jié)果都是對(duì)象。 表2-1. 變量類(lèi)型檢查 ——————————————————————————————— Variable typeof Variable Variable.constructor ——————————————————————————————— {an:"object"} object Object ["an","array"] object Array function(){} function Function "a string" string String 55 number Number true boolean Boolean new User() object User —————————————————————————————————— 使用表2-1的信息你現(xiàn)在可以創(chuàng)建一個(gè)通用的函數(shù)用來(lái)在函數(shù)內(nèi)進(jìn)行類(lèi)型檢查。可能到現(xiàn)在已經(jīng)明顯,使用一個(gè)變量的constructor作為對(duì)象類(lèi)型的引用可能是最簡(jiǎn)單的類(lèi)型檢查方式。當(dāng)你想要確定精確吻合的參數(shù)數(shù)目的類(lèi)型傳進(jìn)了你的函數(shù)時(shí),嚴(yán)格的類(lèi)型檢查在這種可能會(huì)大有幫助。在程序2-9中我們可以看到實(shí)際中的一例。 程序2-9. 一個(gè)可用來(lái)嚴(yán)格維護(hù)全部傳入函數(shù)的參數(shù)的函數(shù)
//依據(jù)參數(shù)列表來(lái)嚴(yán)格地檢查一個(gè)變量列表的類(lèi)型 function strict( types, args ) {
//確保參數(shù)的數(shù)目和類(lèi)型核匹配 if ( types.length != args.length ) { //如果長(zhǎng)度不匹配,則拋出異常 throw "Invalid number of arguments. Expected " + types.length + ", received " + args.length + " instead."; }
//遍歷每一個(gè)參數(shù),檢查基類(lèi)型 for ( var i = 0; i < args.length; i++ ) { //如JavaScript某一項(xiàng)類(lèi)型不匹配,則拋出異常 if ( args[i].constructor != types[i] ) { throw "Invalid argument type. Expected " + types[i].name +", received " + args[i].constructor.name + " instead."; } } }
//用來(lái)打印出用戶列表的一個(gè)簡(jiǎn)單函數(shù) function userList( prefix, num, users ) { //確保prefix是一個(gè)字符串,num是一個(gè)數(shù)字, //且user是一個(gè)數(shù)組 strict( [ String, Number, Array ], arguments ); //循環(huán)處理num個(gè)用戶 for ( var i = 0; i < num; i++ ) { //顯示一個(gè)用戶的信息 print( prefix + ": " + users[i] );
變量類(lèi)型檢查和參數(shù)長(zhǎng)度校驗(yàn)本身是很簡(jiǎn)單的概念,但是可用來(lái)實(shí)現(xiàn)復(fù)雜的方法,給開(kāi)發(fā)者和你的代碼的使用者提供更好的體驗(yàn)。接下來(lái),我們將探討JavaScript中的作用域以及怎么更好的控制它。
出處:藍(lán)色理想
責(zé)任編輯:moby
上一頁(yè) 語(yǔ)言特性:引用 下一頁(yè) 語(yǔ)言特性:作用域
◎進(jìn)入論壇網(wǎng)頁(yè)制作、網(wǎng)站綜合版塊參加討論
|