首先試一下兩段代碼的不同結果
代碼一
var Util = {
Math: function() {
if (arguments.length === 1) {
return Number(arguments[0]);
}
var left = Number(arguments[0]);
var right = Array.prototype.splice.call(arguments, 1);
return left + Util.Math.apply(this, right);
}
}
var NewUtil = { NewMath: Util.Math };
Util = {};
alert(NewUtil.NewMath(1, 2, 3, 4, 5, 6, 7, 8, 9));
代碼二
var Util = {
Math: function MathMethod() {
if (arguments.length === 1) {
return Number(arguments[0]);
}
var left = Number(arguments[0]);
var right = Array.prototype.splice.call(arguments, 1);
return left + MathMethod.apply(this, right);
}
}
var NewUtil = { NewMath: Util.Math };
Util = {};
alert(NewUtil.NewMath(1, 2, 3, 4, 5, 6, 7, 8, 9));
第二種方式的說明
var Util = {
//使用遞歸方法來實現數值數組的連加
//第一種方式中使用的是匿名函數,必須要通過this或者Util才能調用到Math方法,
//而第二種是爲其函數命名,函數名本身也是一個變量,考慮到函數的閉包的特性,
//這個函數名變量會保留下來,即使Util被清空
Math: function MathMethod() {
//因爲數組的變量數無法控制所以採用arguments來取得參數
if (arguments.length === 1) {
//當判斷數組的最後一個數值後返回結果
return Number(arguments[0]);
}
//每次取得第一個參數
var left = Number(arguments[0]);
//將剩下的參數從arguments參數列表的第二位開始截取
//這裏有一個問題因爲arguments雖然有length變量,但是它並不是數組
//爲了使用數組的splice方法採用Array.prototype.splice.call方式,
//爲數組指定作用域,有的書中說可以將其理解爲對Array對象的欺騙,個人覺得這個比喻非常之貼切,呵呵
var right = Array.prototype.splice.call(arguments, 1);
//計算得到結果
return left + MathMethod.apply(this, right);
}
}
順便提一句
//該方式主要用於定義工具對象,既直接被調用的
var Util = {}
//該方式主要用於定義類對象,既New實例化之後在使用
var Util = function(){}