JS中模拟函数重载
作者:LuLi 来源:SimpleLife 发布时间:2008-01-03 16:46:00
在面向对象的编程中,很多语言都支持函数重载,能根据函数传递的不同个数、类型的参数来做不同的操作,JS对它却不支持,需要我们额外做些小动作。
在JS的函数执行上下文中有一个名为arguments的有意思的变量,它以数组的形式存储了函数执行时传递过来的所有参数,即使函数定义没有定义这么多个形参。还有一个特别之处就是跟Array类型相比,arguments变量有且只有一个length属性,Array的方法,例如push、pop等,它并不具备,它只是一个“伪数组”:具有length属性,存储的数组能够用数组访问符[]来访问,并且是只读不可写。
一、对于不同个数参数的重载
这里应该很明白,直接用arguments函数的length属性来判断就可以了。
var len = arguments.length;
//传递过来一个参数的时候执行
if(len==1){
alert("Function say:"+msg);
}
//传递过来两个参数的时候执行
else if(len==2){
handler(msg);
}
}
talk("demo");
talk("demo",function(w){alert("Handler say:"+w);});
二、对于不同类型的参数的重载
对于JS这样一种动态类型的语言,这种变量声明的随意性淡化了严格的变量类型在开发人员脑子里的重要性(PS:同样是基于ECMA体系的,AS就引入了变量声明的强制类型),很多意想不到的BUG其实都是由这种变量类型的自动转换造成的。其实JS提供了很准确的方法让我们来严格检测变量的类型,比较通用的就是typeof方法和constructor属性。
1、typeof variable 返回变量类型
temp = "say"; //string
temp = 1; //number
temp = undefined; //undefined
temp = null; //object
temp = {}; //object
temp = []; //object
temp = true; //boolean
temp = function (){} //function
alert(typeof temp);
通过上面的测试你可以看出来,对于null,Object,Array返回的都是object类型,而使用下面的方法就可以解决这个困扰。
2.constructor属性检测变量类型
JS中每个对象都有constructor属性,它是用来引用构造此对象的函数,通过对这个引用的判断就可以检测变量类型了。
temp = "say";
temp.constructor==String; //true
temp= {};
temp.constructor == Object;//true
temp= [];
temp.constructor == Array;//true
通过上面的测试已经很容易的把Array和Object类型的变量区分开了。下面我们来对自定义的对象做个测试看看会发生什么。
//自定义对象
function Ball(){}
//实例化一个对象
var basketBall = new Ball();
basketBall.constructor==Ball; //true
这可以说明constructor属性对于自定义的对象一样适用。
在弄清楚了上面两个方法的适用以后再来回到JS函数重载的模拟上来,下面这个例子是根据参数类型来重载。
function talk(msg){
var t = typeof msg;
if(t=="string"){
alert("It's a string");
}
else if(t=="number"){
alert("It's a number");
}
}
talk(10); //It's a string
talk("demo"); //It's a number
附上一个很巧妙的严格检测参数类型和个数的函数:
//依据参数列表来严格地检查一个变量列表的类型
function strict( types, args ) {
//确保参数的数目和类型核匹配
if ( types.length != args.length ) {
//如果长度不匹配,则抛出异常
throw "Invalid number of arguments. Expected " + types.length +
", received " + args.length + " instead.";
}
//遍历每一个参数,检查基类型
for ( var i = 0; i < args.length; i++ ) {
//如JavaScript某一项类型不匹配,则抛出异常
if ( args[i].constructor != types[i] ) {
throw "Invalid argument type. Expected " +
types[i].name +", received " +
args[i].constructor.name + " instead.";
}
}
}
//上述方法的使用
function doFunction(id,name){
//检测参数个数和类型
strict([Number,String],arguments);
..
}


猜你喜欢
- 前言DISTINCT 实际上和 GROUP BY 操作的实现非常相似,只不过是在 GROUP BY 之后的每组中只取出一条记录而已。所以,D
- 大家好,今天我们要看看如何用 Python制作音乐播放器。此音乐播放器播放您的歌曲,您可以在播放歌曲时暂停、恢复、设置音量,然后您可以停止音
- 出自: 编程中国 http://www.bc-cn.net作者: 天涯听雨 &nbs
- 前言忘了在哪看到一位编程大牛调侃,他说程序员每天就做两件事,其中之一就是处理字符串。相信不少同学会有同感。在Python中,我们经常会遇到字
- PyQt5安装在cmd下输入pip install PyQt5完成PyQt5安装,再安装qt designer,可以使用pip安装pip i
- 这是由十几位视觉设计师设计的挂历,每个月份都是不同的风格,就像每个月都有不同温度和心情一样,思维跳跃性很大,可以作为挂历设计参考。当然,如果
- 本文实例为大家分享了js实现本地持久化存储登录注册的具体代码,供大家参考,具体内容如下1.登录html文件<!DOCTYPE html
- 计算信息熵的公式:n是类别数,p(xi)是第i类的概率假设数据集有m行,即m个样本,每一行最后一列为该样本的标签,计算数据集信息熵的代码如下
- 用python实现FTP文件传输,包括服务器端和客户端,要求(1)客户端访问服务器端要有一个验证功能(2)可以有多个客户端访问服务器端(3)
- 本文讲述了线程安全及Python中的GIL。分享给大家供大家参考,具体如下:摘要什么是线程安全? 为什么python会使用GIL的机制?在多
- 项目中用到了限流,受限于一些实现方式上的东西,手撕了一个简单的服务端限流器。服务端限流和客户端限流的区别,简单来说就是:1)服务端限流对接口
- 前言sys模块是与python解释器交互的一个接口。sys 模块提供了许多函数和变量来处理 Python 运行时环境的不同部分。处理命令行参
- 前言在之前的面试过程中,问到执行计划,有很多童鞋不知道是什么?甚至将执行计划与执行时间认为是同一个概念。今天我们就一起来了解一下执行计划到底
- 【前言】 之前由于小编的错误操作误删了注册表中的一项关于sql的内容,具体删了什么,也忘
- 先来看一个老掉牙的故事:福特说,我在设计汽车之前,到处去问人们“需要一个什么样的更好的交通工具?”,几乎所有人的答案都是 ── 一匹“更快的
- 基本概念简单地说,Node.js是在服务器端运行的JavaScript。 节点。$ node> console.log('He
- 在开发过程中,有时遇到由于缓存问题导致页面不能及时更新,有时页面引入了不必需的样式脚本文件,有时由于文件太多,字节过大导致页面的性能缓慢,为
- 可以的,看看下面的代码和说明:<%sessionID = session.SessionIDtimeout&nbs
- 本文实例讲述了python实现bucket排序算法。分享给大家供大家参考。具体实现方法如下:def bucketSort(a, n, buc
- 今天介绍下Psyco模块,Psyco模块可以使你的Python程序运行的像C语言一样快。都说Python语言易用易学,但性能上跟一些编译语言