2013-07-19 22 views
0

编辑:我发现这个有趣的库,它看起来像它可以做的正是我一直在底部的描述:https://github.com/philbooth/check-types.jsJavascript:如何确保参数具有特定的界面?

看起来你可以通过调用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); 
} 

然后我可以重复使用这些接口之间我不同的功能,并定义扩展它们传递到我的功能,而无需担心拼写错误的属性名称或传递错误的参数对象。关于如何实现这一点,或者我可以利用现有实现的任何想法?

回答

0

我没有看到任何其他方式来执行此操作。这是JavaScript动态特性的副作用之一。它基本上是一个免费的所有人,并与自由来负责:-)

+0

虽然这不是一个真正的责任问题,它更像是预防性护理。我都在设计和遵循标准来保持结构化代码,但代码总是容易出错。不可避免的是你会犯错,而当你这样做时,我希望它更容易调试。 – Alex

+0

@Alex我同意您的声明JavaScript可能不安全。团队中的人员可能会调用构造函数,传递错误的类型参数,设置或删除私有变量以及其他一些危险。您不能剥夺JavaScript获得这些检查的灵活性,但您可以使用工具编译代码以进行类型检查。 – HMR

0

如果你需要类型检查你可以看看打字稿(这不是JavaScript)或谷歌的封闭编译器(javascript与注释)。

Closure编译器使用注释来确定在编译时需要什么类型。看起来很麻烦,但可以在大型项目中有所帮助。

闭包编译器还有其他一些好处,因为您将被迫生成在NetBeans IDE中使用的注释,它将代码缩小,删除未使用的代码并平滑命名空间。因此,将像myApp.myModule.myObject.myFunction这样的名称空间中组织的代码展平,以尽量减少对象查找。

缺点是当你使用类似jQuery的编译器不兼容的库时,你需要使用externs。

+0

打字稿限制JavaScript的功能吗?或者它只是允许错误检查?我仍然希望能够像动态地向对象添加属性一样。以及如何将其与JavaScript库集成起作用? – Alex

+0

@Alex Typescript是JavaScript的新增功能。如果你不使用这些特性,它只是JavaScript,你不需要编译它。 Closure编译器使用JavaScript中的注释来进行类型检查,但是如果你有'我知道我在做什么'的代码,你可以使用surpress标签关闭每个文件或函数的这些检查。 – HMR

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

如果你真的想在运行时,如果未提供特定成员抛出错误,你也许可以定义抛出一个错误的功能,并将其包含在您的默认值。因此,如果一个成员是由调用者提供的,它将覆盖默认值,但是如果它错过了,它可能会采取一些默认功能或根据您的意愿抛出错误。

+0

我在很多地方使用默认参数。但在这种情况下,我不想指定默认行为,我想确保传递的参数指定该行为。如果我给它默认的行为,那么偶然传入一个不完整的接口会产生更微妙的错误。在默认参数中抛出异常比留下未定义的更好,但仍会在不同的级别抛出错误,并且这对于非函数属性不起作用。 – Alex

相关问题