首先试一下两段代码的不同结果
代码一
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(){}