1

我正在尝试在 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”作为对象似乎很奇怪。

我还有第二个问题:所有这些错误检查内容值得付出努力吗?它使代码的大小加倍,使其读取和写入的时间更长,并且由于属性是公共的,因此不能完全防止出现 null 或 undefined 值。

谢谢你的帮助 :)

4

2 回答 2

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;
}

至于测试你的参数,我会说放松。要么将其包装在报告参数存在问题的 try/catch 中,要么学习信任不依赖外部资源的函数中的数据。当您学会了解通过应用程序的数据流并且您充分了解所有动态转换规则以了解出现问题时会发生什么时,整个动态类型的事情就不那么可怕了,如果发生这种情况并不常见你的尽职尽责,你甚至应该在严格类型的范式中

于 2012-12-14T14:21:32.383 回答
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
于 2012-12-14T20:21:22.210 回答