【问题标题】:JavaScript - Flexible argumentsJavaScript - 灵活的参数
【发布时间】:2012-12-14 14:03:05
【问题描述】:

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

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

感谢您的帮助:)

【问题讨论】:

  • 您可以创建一个简单的overload 函数,其签名如(func, types, newFunc),其中types 是新声明函数的typeof 值数组。然后,您可以分离重载逻辑和不同的功能。
  • 感谢您的回答。我不确定你的想法。

标签: javascript object error-handling arguments


【解决方案1】:

我不认为这很糟糕,但在 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 中,要么学会信任不依赖外部资源的函数中的数据。当您学会了解通过应用程序的数据流并且您充分了解所有动态转换规则以了解出现问题时发生的情况时,整个动态类型的事情就不那么可怕了,如果发生这种情况并不常见你的尽职尽责,即使在严格类型的范式中也应该如此

【讨论】:

  • 感谢您的回答! “即使不计算上限,也不需要 var dec”到底是什么意思?
  • 另外,如果我的对象中有方法,使用this.constructor.prototype = coordsObj; 将删除该方法,不是吗?
  • 即使 if 条件不成立,var 也被视为已声明,因此您无需在 if/else 中声明两次。原型就像一个备份对象来检查您的实例上是否不存在方法,因此它们实际上不会覆盖实例上的任何内容。这就是为什么您可以向构造函数原型添加方法,并且您已经创建的实例也可以访问该方法。
【解决方案2】:

我对@9​​87654323@ 函数的想法如下:您可以创建一个接受函数的函数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-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    • 2015-02-01
    • 2022-01-06
    • 1970-01-01
    • 2011-10-08
    相关资源
    最近更新 更多