JavaScript完成函数重载
函数重载(function overloading),是 Ada、C++、C#、D、Java等编程言语中具有的一项特征,这项特征许可建立数项称号雷同但输入输出范例或个数差别的子程序,它能够简朴地称为一个零丁功用能够实行多项使命的才能。
维基百科-函数重载
函数重载是强范例言语的特征,虽然 js 是弱范例言语,我们能够经由过程一些要领完成函数重载。
场景
班级中有许多门生,经由过程姓名要找到某个门生或多个门生时,同一个要领传入的参数个数的差别去查找同砚。
const classRoom = {
students: ['武大', '郎二', '张三', '张起灵', '李四', '王五'],
}
classRoom.find(); // ['武大', '郎二', '张三', '张起灵', '李四', '王五'];
classRoom.find('张'); // ['张三', '张起灵'];
classRoom.find('张', '三'); // ['张三'];
-
find()
要领不传入参数时,输出班级一切门生。 -
find()
要领传一个参数(姓),输入班级雷同姓的门生。 -
find()
要领传两个个参数(姓,名),输入班级雷同姓名的门生。
第一种
我们运用 arguments 和 switch 完成重载。
classRoom.find = function() {
switch(arguments.length) {
case 0:
return this.students;
case 1:
return this.students.filter(student => {
let surname = arguments[0];
return ~student.indexOf(surname);
});
case 2:
return this.students.filter(student => {
let fullName = Array.prototype.slice.call(arguments).join('');
return ~student.indexOf(fullName);
});
}
}
console.log(classRoom.find()); // [ '武大', '郎二', '张三', '张起灵', '李四', '王五' ]
console.log(classRoom.find('张')); // [ '张三', '张起灵' ]
console.log(classRoom.find('三')); // [ '张三' ]
第二种
运用 arguments 和闭包。
function addMethod(target, name, fn) {
const old = target[name];
target[name] = function() {
if (fn.length === arguments.length) {
return fn.apply(this, arguments);
} else if (typeof old === 'function') {
return old.apply(this, arguments);
}
}
}
addMethod(classRoom, 'find', function() {
return this.students;
});
addMethod(classRoom, 'find', function(surname) {
return this.students.filter(student => {
return ~student.indexOf(surname);
});
});
addMethod(classRoom, 'find', function(surname, personalName) {
return this.students.filter(student => {
return ~student.indexOf(surname + personalName);
});
});
console.log(classRoom.find()); // [ '武大', '郎二', '张三', '张起灵', '李四', '王五' ]
console.log(classRoom.find('张')); // [ '张三', '张起灵' ]
console.log(classRoom.find('三')); // [ '张三' ]
挪用addMethod
时会将匿名函数指向classRoom
中的find
,因为classRoom
是全局变量所以addMethod
实行终了后个中的old
、fn
依然在被援用,这里发生闭包。
所以在每次挪用addMethod
时,都有一个实行环境保存着当时的old
以及fn
,所以在运用find
要领是能够找到fn
,完成重载。
须要注重的是:
- 这个重载适用于差别数目的参数,不辨别范例、参数名或别的。
- 会有一些函数挪用的开支。
别的
在 TypeScript 中加入了范例,它自带函数重载。ts函数