Javascript:如何确保参数具有特定的接口?

时间:2013-07-19 01:16:33

标签: javascript interface parameters arguments contract

编辑:我发现这个有趣的库看起来像我在底部所描述的那样:https://github.com/philbooth/check-types.js

看起来你可以通过调用check.quacksLike来实现。


我对使用javascript很新,我喜欢它提供的功率,但有时它太灵活,我的理智无法处理。我想要一种简单的方法来强制某些参数尊重特定的接口。

这是一个突出我问题的简单示例方法:

var execute = function(args)
{
    executor.execute(args);
}

假设执行者希望args拥有一个名为cmd的属性。如果未定义,则当程序尝试引用cmd时,可能会在另一级别捕获错误,但它是undefined。调试比在此方法中明确强制cmd存在更令人讨厌。执行者甚至可能期望args有一个名为getExecutionContext()的函数,它会被传递一下。我可以想象更复杂的情况,调试很快就会成为追踪函数调用的噩梦,看看哪个参数最初被传入。

我也不想在以下方面做点什么:

var execute = function(args)
{
    if(args.cmd === undefined || args.getExecutionContext === undefined ||
       typeof args.getExecutionContext !== 'function')
        throw new Error("args not setup correctly");
    executor.execute(args);
}

这将为每个具有参数的函数提供大量维护,尤其是对于复杂的参数。我宁愿能够指定一个接口,并以某种方式强制执行一个合同,告诉javascript我希望输入匹配此接口。

可能是这样的:

var baseCommand =
{
    cmd: '',
    getExecutionContext: function(){}
};

var execute = function(args)
{
    enforce(args, baseCommand); //throws an error if args does not honor
                                //baseCommand's properties
    executor.execute(args);
}

然后我可以在我的不同函数中重用这些接口,并定义扩展它们的对象以传递给我的函数,而不必担心拼写错误的属性名称或传入错误的参数。关于如何实现这个或者我可以利用现有实现的任何想法?

3 个答案:

答案 0 :(得分:0)

我没有看到任何其他方法来强制执行此操作。这是JavaScript动态特性的副作用之一。它本质上是一个免费的,并且自由带来责任:-)

答案 1 :(得分:0)

如果您需要进行类型检查,可以查看typescript(它不是JavaScript)或google的闭包编译器(带注释的javascript)。

Closure编译器使用注释来确定编译时期望的类型。看起来很麻烦,但在大型项目中可能会有所帮助。

封闭编译器还有其它好处,因为您将被迫生成IDE中使用的注释,如netbeans,它会缩小代码,删除未使用的代码并展平命名空间。因此,在myApp.myModule.myObject.myFunction等命名空间中组织的代码将被展平,以最大限度地减少对象查找。

缺点是,当您使用与jQuery不兼容的编译器时,需要使用externs。

答案 2 :(得分:0)

这种事情通常在javascript中处理的方式是使用默认值。大多数情况下,您只是想提供某些成员存在的保证,以防止引用错误之类的事情,但我认为您可以使用委托人来获得您想要的内容。

通过使用类似jQuery的扩展方法,我们可以保证参数实现了一组定义的默认值。

    var defaults = {
        prop1: 'exists',
        prop2: function() { return 'foo'; }
    };

    function someCall(args) {
        var options = $.extend({}, defaults, args);
        // Do work with options... It is now guarentee'd to have members prop1 and prop2, defined by the caller if they exist, using defaults if not.
    }

如果您确实想在运行时抛出错误,如果未提供特定成员,您可以定义一个抛出错误的函数,并将其包含在默认值中。因此,如果一个成员是由调用者提供的,它将覆盖默认值,但是如果它被遗漏,它可以采用某些默认功能或者根据需要抛出错误。