JavaScript - 灵活的参数

时间:2012-12-14 14:03:05

标签: javascript object error-handling arguments

我正在尝试在JavaScript中创建一个小结构,我将在库中用于画布。我希望在创建这个结构时传递的参数可以像我们在编译语言中那样是多个参数,或者是一个具有与这些参数相对应的属性的对象:

BoundingBox = function( x, y, w, h ) {

    if( 'object' === typeof x ) {

        if( ! 'x' in x ) throw new Error('Property "x" missing');
        if( ! 'y' in x ) throw new Error('Property "y" missing');
        if( ! 'w' in x ) throw new Error('Property "w" missing');
        if( ! 'h' in x ) throw new Error('Property "h" missing');

        this.x = x.x;
        this.y = x.y;
        this.w = x.w;
        this.h = x.h;

    } else {

        if( null == x ) throw new Error('Parameter 1 is missing');
        if( null == y ) throw new Error('Parameter 2 is missing');
        if( null == w ) throw new Error('Parameter 3 is missing');
        if( null == h ) throw new Error('Parameter 4 is missing');

        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    }
};

然后:

var bb1 = new BoundingBox(0, 0, 200, 100);

var bb2 = new BoundingBox({
    x: 0,
    y: 0,
    w: 200,
    h: 100
});

var bb3 = new BoundingBox(bb2);

这是一种干净的方式吗?在我们使用对象的情况下,使用“x”作为对象似乎非常奇怪。

我还有第二个问题: 是否所有错误检查都值得努力?它使代码的大小加倍,使读取和写入时间更长,并且由于属性是公共的,所以不能完全防止具有空值或未定义的值。

感谢您的帮助:)

2 个答案:

答案 0 :(得分:2)

我认为这不是很糟糕,但在JavaScript中,通过每个函数可用的参数var可以更加一般地完成重载。

function BoundingBox(){

//do named functions with constructors. It sets the constructor.name
//property in instances, which can be handy sometimes

    if(typeof arguments[0] === 'object'){
        var coordsObj = arguments[0];
    }
    else {
        coordsObj = {} //no need for var dec even when upper if doesn't evaluate
        coordsObj.x = arguments[0];
        coordsObj.y = argumetns[1];
        //...etc.
    }
    //laziest way to make those publicly available.
    this.constructor.prototype = coordsObj;
}

至于测试你的params,我会说放松。将它包装在try / catch中,报告params存在问题或学习信任不依赖外部源的函数中的数据。当你学会通过你的应用程序了解数据流时,整个动态类型的东西就不那么可怕了,你可以很好地了解所有动态强制转换规则,以便在出现问题时了解发生了什么,这种情况并不常见。你尽职尽责,你应该在严格打字的范例中

答案 1 :(得分:0)

我对overload函数的想法如下:您可以创建一个接受函数的函数overload,以及一个带有其签名的新函数(作为typeof值的数组)。然后,返回的函数检查当前调用是否与此签名匹配,并在这种情况下调用新函数。否则它会调用旧函数。

这样,您可以通过多次修补来重载函数。可以通过这种方式分离不同功能和实际重载逻辑的定义。请参阅http://jsfiddle.net/m2cRK/

​var overload = function(oldFunc, types, newFunc) {
    return function() {
        var suffice = Array.prototype.every.call(arguments, function(v, i) {
            return typeof v === types[i];
        });
        return (suffice ? newFunc : oldFunc).apply(this, arguments);
    };
};

用法(这是一个不需要重新分配的函数:http://jsfiddle.net/m2cRK/1/):

// The end of the chain, e.g. a function that throws a "no overload" error
var foo = overloadStart();

// Function 1
foo = overload(foo, ["number", "number"], function(a, b) {
    return a + b;
});

// Function 2
foo = overload(foo, ["object"], function(obj) {
    return obj.a + obj.b;
});


foo(1, 2);            // 3
foo({ a: 1, b: 2 });  // 3
foo("bar");           // error