function aaa(sTemplate) { var args = arguments; var s = sTemplate; s = s.replace(/\%\%/g, "%"); for (var i = 1; i < args.length; i++) s = s.replace( new RegExp("\%" + i + "\%", "g"), args[i] ) return s;}
arguments雖然不是數組,但可以當作數組使用,下標由0 開始,所以:
arguments[0] 表示接收的第一個參數
arguments[1] ……
如此類推……
這樣就可以實現不同參數調用同一個函數了~
當然,前提是函數設置了對該參數的處理方法,不然還是白搭
arguments 屬性
為目前執行的function 物件傳回一個arguments 物件。
function.arguments
function 參數是目前執行函數的名稱,可以省略。
arguments 物件的 length 屬性包含了傳遞給函數的參數的數目。 arguments 物件所包含的單一參數,存取方法與陣列中所包含的參數的存取方法相同。
摘抄了一個範例,說明了 arguments 屬性的用法。可以參考:
function ArgTest(){ var i, s, numargs = arguments.length; s = numargs; if (numargs < 2){ s += " argument was passed to ArgTest. It was "; }else{ s += " arguments were passed to ArgTest. They were " ; } for (i = 0; i < numargs; i++){ s += arguments[i] + " "; } return(s); }
引用:
一、巧用arguments
在 Javascript 的函數中有個名為 arguments 的類別陣列物件。它看起來是那麼的詭異而且名不經傳,但眾多的 Javascript 函式庫都使用著它強大的功能。所以,它的特性需要每個 Javascript 程式設計師去熟悉它。
在每個函數中,都有一個名為 arguments 的變量,它以類似數組的形式保存了目前調用的參數。而它實際上並不是一個數組,使用 typeof arguments 語句嘗試會傳回「object」(物件),所以它不能像 Array 一樣使用 push 和 pop 等方法。即便如此,仍然可以使用下標以及長度屬性(length)來取得它的值。
二、寫出靈活的函數
雖看起來名不經傳,但的確 arguments 是非常有用的物件。例如,你可以讓函數處理不定數目的參數。在Dean Edwards 寫的base2 函式庫中,有個叫format 的函數充分發揮了這一特性:
function format(string) { var args = arguments; var pattern = new RegExp("%([1-" + arguments.length + "])", "g"); return String(string).replace(pattern, function(match, index) { return args[index]; }); };
replace這個函數的第二個參數可以為一個函數,函數的第一個參數可以為匹配了的文字,第二個參數為第幾個匹配的值,返回值為要進行替換的文字
這個函數實現了模板替換,你可以在要動態替換的地方使用%1 到%9 標記,然後其餘的參數就會依序替換這些地方。例如:
format("And the %1 want to know whose %2 you %3", "papers", "shirt", "wear");
上面的腳本就會回傳
"And the papers want to know whose shirt you wear" 。
在這裡需要注意的是,即便在 format 函數定義中,我們僅定義了個名為 string 的參數。而 Javascript 不管函數本身定義的參數數量,它都允許我們向一個函數傳遞任意數量的參數,並將這些參數值保存到被呼叫函數的 arguments 物件中。
三、轉換成實際陣列
雖然arguments 物件並不是真正意義上的Javascript 數組,但我們可以使用陣列的slice 方法將其轉換成數組,類似下面的程式碼
. .slice.call(arguments);
call(obj,當前函數使用的參數列表)
call方法第一個參數為一個物件,這個傳進去的物件將呼叫slice函數.因為arguments不是一個陣列,所以不能直接呼叫slice方法,所以只能使用''物件冒充''方法了
這樣,陣列變數args 包含了所有arguments 物件所包含的值。
四、讓參數建構函數
使用 arguments 物件能夠簡短我們所寫的 Javascript 程式碼量。下面有一個名為 makeFunc 的函數,它根據你提供的函數名稱以及其他任意數目的參數,然後回傳一個匿名函數。此匿名函數被呼叫時,合併的原先被呼叫的參數,並交給指定的函數執行然後返回其返回值。
function makeFunc() { var args = Array.prototype.slice.call(arguments); var func = args.shift(); return function() { return func.apply(null, args.concat(Array.prototype.slice.call(arguments))); }; }
arguments有一個不可枚舉的屬性callee(不能用for in讀出,可用HasOwnProterty(name)來判斷),arguments.callee為正被執行的 Function 物件。 slice時己把目前函數指標copy了過去,所以args的第一個元素為函數型別
makeFunc 的第一個參數指定需要呼叫的函式名稱(是的,在這個簡單的例子中沒有錯誤檢查),取得日後從args 刪除。 makeFunc 傳回一個匿名函數,它使用函數物件的(Function Object)apply 方法呼叫指定的函數。
apply 方法的第一個參數指定了作用域,基本上的作用域是被呼叫的函數。不過這樣在這個例子中看起來會有點複雜,所以我們將其設定成 null ;其第二個參數是個數組,它指定了其呼叫函數的參數。 makeFunc 轉換其自身的 arguments 並連接匿名函數的 arguments,然後傳遞到被呼叫的函數。
有种情况就是总是要有个输出的模板是相同的,为了节省每次是使用上面提到的 format 函数并指定重复的参数,我们可以使用 makeFunc 这个工具。它将返回一个匿名函数,并自动生成已经指定模板后的内容:
var majorTom = makeFunc(format, "This is Major Tom to ground control. I'm %1.");
你可以像这样重复指定 majorTom 函数:
majorTom("stepping through the door");
majorTom("floating in a most peculiar way");
那么当每次调用 majorTom 函数时,它都会使用第一个指定的参数填写已经指定的模板。例如上述的代码返回:
"This is Major Tom to ground control. I'm stepping through the door."
"This is Major Tom to ground control. I'm floating in a most peculiar way."
五、自引用的函数
您可能会认为这很酷,先别急着高兴,后面还有个更大的惊喜。它(arguments)还有个其他非常有用的属性:callee 。arguments.callee 包含了当前调用函数的被引用对象。那么我们如何使用这玩意做些的事情?arguments.callee 是个非常有用的调用自身的匿名函数。
下面有个名为 repeat 的函数,它的参数需要个函数引用和两个数字。第一个数字表示运行的次数,而第二个函数定义运行的间隔时间(毫秒为单位)。下面是相关的代码:
function repeat(fn, times, delay) { return function() { if(times-- > 0) { fn.apply(null, arguments); var args = Array.prototype.slice.call(arguments); var self = arguments.callee; setTimeout(function(){self.apply(null,args)}, delay); } }; }
repeat 函数使用 arguments.callee 获得当前引用,保存到 self 变量后,返回个匿名函数重新运行原本被调用的函数。最后使用 setTimeout 以及配合个匿名函数实现延迟执行。
作为个简单的说明,比如会在通常的脚本中,编写下面的提供个字符串并弹出个警告框的简单函数:
function comms(s) { alert(s); }
好了,后来我改变了我的想法。我想编写个“特殊版本”的函数,它会重复三次运行每次间隔两秒。那么使用我的 repeat 函数,就可以像这样做到:
var somethingWrong = repeat(comms, 3, 2000);
somethingWrong("Can you hear me, major tom?");
结果就犹如预期的那样,弹出了三次警告框每次延时两秒。
最后,arguments 即便不会经常被用到,甚至显得有些诡异,但是它上述的那些惊艳的功能(不仅仅是这些!)值得你去了解它。
undefined ≠ null
null是一个对象,undefined是一个属性、方法或变量。存在null是因为对象被定义。如果对象没有被定义,而测试它是否是null,但因为没有被定义,它无法测试到,而且会抛出错误。
if(myObject !== null && typeof(myObject) !== 'undefined') { //如果myObject是undefined,它不能测试是否为null,而且还会抛出错误 } if(typeof(myObject) !== 'undefined' && myObject !== null) { //处理myObject的代码 }