实践:
将下面示例以重载方式实现:
/*
* 重载
*/
function fn(name) {
console.log(`我是${name}`)
}
function fn(name, age) {
console.log(`我是${name},今年${age}岁`)
}
function fn(name, age, sport) {
console.log(`我是${name},今年${age}岁,喜欢运动是${sport}`)
}
/*
* 理想结果
*/
fn('林三心') // 我是林三心
fn('林三心', 18) // 我是林三心,今年18岁
fn('林三心', 18, '打篮球') // 我是林三心,今年18岁,喜欢运动是打篮球
实现一:switch+case
只写一个fn
函数,并在这个函数中判断arguments
类数组的长度,执行不同的代码,就可以完成重载的效果
function fn() {
switch (arguments.length) {
case 1:
var [name] = arguments
console.log(`我是${name}`)
break;
case 2:
var [name, age] = arguments
console.log(`我是${name},今年${age}岁`)
break;
case 3:
var [name, age, sport] = arguments
console.log(`我是${name},今年${age}岁,喜欢运动是${sport}`)
break;
}
}
/*
* 实现效果
*/
fn('林三心') // 我是林三心
fn('林三心', 18) // 我是林三心,今年18岁
fn('林三心', 18, '打篮球') // 我是林三心,今年18岁,喜欢运动是打篮球
实现方式二:闭包
function addMethod(object, name, fn) {
var old = object[name]; //把前一次添加的方法存在一个临时变量old里面
object[name] = function () { // 重写了object[name]的方法
// 如果调用object[name]方法时,传入的参数个数跟预期的一致,则直接调用
if (fn.length === arguments.length) {
return fn.apply(this, arguments);
// 否则,判断old是否是函数,如果是,就调用old
} else if (typeof old === "function") {
return old.apply(this, arguments);
}
}
}
addMethod(window, 'fn', (name) => console.log(`我是${name}`))
addMethod(window, 'fn', (name, age) => console.log(`我是${name},今年${age}岁`))
addMethod(window, 'fn', (name, age, sport) => console.log(`我是${name},今年${age}岁,喜欢运动是${sport}`))
/*
* 实现效果
*/
window.fn('林三心') // 我是林三心
window.fn('林三心', 18) // 我是林三心,今年18岁
window.fn('林三心', 18, '打篮球') // 我是林三心,今年18岁,喜欢运动是打篮球
所有的函数都有一个length属性,这个属性的值等于该函数声明时所需要传入值的数量。
利用闭包的特性,addMethod()每一次的调用都会产生一个新的匿名函数。并且这个新的匿名函数通过闭包包含着一个old对象。
old方法中包含之前旧的方法。这样就像洋葱一样一层一层。通过闭包访问old和fn来实现函数的重载。