JavaScript的语言特性 — 函数重载和类型检查

前端技术 everyinch 6021℃ 0评论

其他面向对象语言的一个常见特性是,能够根据传入的不同数量或类型的参数,通过“重载(overload)”函数来发挥不同的功用。尽管这个特性在JavaScript中并没有被直接支持,也有很多种办法能够实现。

函数重载(function overloading)必须依赖两件事情:传入参数的数量和传入参数的类型。

JavaScript中每个函数都带有一个仅在这个函数范围作用的变量(contextual variable)成为 arguiments,它是一个包含所有传给函数的参数的伪数组(pseudo-array),它不是一个真正意义上的数组,不能修改它,也不能用 push() 来添加元素,但可以访问其中的元素,也具有 length 属性。

// 发送一条信息的简单函数
function sendMessage( msg, obj ) {
    // 如果消息和对象(的参数)都被提供
    if ( arguments.length == 2 )
        // 给对象发送消息
        obj.alert( msg );

    // 否则,假定只提供了一条消息
    else
        // 那么仅显示默认的错误信息
        alert( msg );
}

// 仅用一个参数调用这个函数,用 alert 来显示此消息
sendMessage( "Hello, World!" );
sendMessage( "How are you?", {
	handleMsg:function(msg){
		alert("This is a custom message: " + msg);
	}
});

// 一个接收任意数量参数并将其转换为数组的函数
function makeArray() {
    // 临时数组
    var arr = [];

    // 遍历传入的每个参数
    for ( var i = 0; i < arguments.length; i++ ) {
        arr.push( arguments[i] );
    }

    // 返回结果数组
    return arr;
}

对于传入参数类型的判断,如果没有向函数提供参数,它的类型一定是 undefined,可以利用这个特性来做判断。例如:实现这样一个简单函数,它用于显示错误信息,如果没有提供信息的内容,就显示默认的信息。

function displayError( msg ) {
    // 检查并确认 msg 是否 undefined
    if ( typeof msg == 'undefined' ) {
        // 如果是,则置 msg 为默认信息
        msg = "An error occurred.";
    }

    // 显示该消息
    alert( msg );
}

如果有参数传递进来,可以使用两种方法来判断变量的类型:第一种方法是使用 typeof 操作符。它提供了一个字符串名称,用来表达变量内容的类型。当变量不是 object 或者 array 类型时,这应该是最完美的解决办法了。但对于自定义对象它只返回object,很难与其它的object区分开来:

// 检查我们的数字是否实际是字符串
if ( typeof num  == "string" )
    // 若是,则根据这个字符串解析出整数来
    num = parseInt( num );

// 检查我们的数组是否实际上是字符串
if ( typeof arr == "string" )
    // 若是,则根据逗号切分出数组来
    arr = arr.split(",");

第二种判断传入参数类型的方法是所有JavaScript对象都带有 constractor 属性,这个属性引用的是原本用来构造该对象的那个函数:

// 检查我们的数字是否实际是字符串
if ( num.constructor == String )
    // 若是,则根据这个字符串解析出整数来
    num = parseInt( num );

// 检查我们的数组是否实际上是字符串
if ( str.constructor == Array )
    // 若是,则根据逗号切分出数组来
    str = str.join(',');

用下表对不同类型对象进行类型检查的结果。第一列是尝试判断类型的对象;第二列是执行typeof的结果,结果是字符串;第三列是constructor属性的结果,结果都是对象

变量

typeof变量

变量.constructor

{an:"object"}

object

Object

["an","object"]

object

Array

Function(){}

function

Function

"a string"

string

String

55

number

Number

true

boolean

Boolean

new User()

object

User

很明显,通过 constructor 属性进行类型检查是最不容易犯错的方法。例如,写一个函数判断传入函数的参数是否有正确的数量和类型:

// 用一个变量类型列表严格检查一个参数列表
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++ ) { if ( args[i].constructor != types[i] ) { throw "Invalid argument type. Expected " + types[i].name + ", received " + args[i].constructor.name + " instead."; } } } // 一个简单的函数,用来打印用户列表 function userList( prefix, num, users ) { // 保证 prefix 是字符串,num 是数字,users 是数组 strict( [ String, Number, Array ], arguments ); // 遍历 ‘num’ 个用户 for ( var i = 0; i < num; i++ ) { // 显示每个用户的信息 alert( prefix + ": " + users[i] ); } } [/code] JavaScript-Web

分享&收藏

转载请注明:陈童的博客 » JavaScript的语言特性 — 函数重载和类型检查

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(3)个小伙伴在吐槽
  1. 你好,http://www.jiedichina.com/product/showproduct13.html
    谭福兴2013-11-18 16:05 回复
  2. 你好,视频里的系统我们想在网页商展示出来。
    谭福兴2013-11-18 16:20 回复
  3. 你好,后台上可以直接把产品、展柜、柱子广告,都可以替换。
    谭福兴2013-11-18 16:20 回复
'; } if( dopt('d_footcode_b') ) echo dopt('d_footcode'); ?>