JavaScript:我可以以某种方式强类型函数参数吗?

时间:2012-03-20 15:28:55

标签: javascript

我是一个使用JavaScript的新手,我觉得强大的类型我的函数参数对于我编写的几个工具的不可抗拒的需求:

  1. 这会让我在这些功能中自动完成
  2. 调试/功能访问变得更加一致
  3. 经过一些谷歌搜索,我想这不是直接可能的。但是,有没有通用的工具可以简单地模仿这个?

    你有什么想法?

8 个答案:

答案 0 :(得分:11)

写作的人"你不应该使用它"错了。在下一个Java Script 2.x规范中,计划添加强类型变量。

同时,您可以使用非常简单的解决方案来模拟强类型:

var = Object.create( String );

之后,在很多IDE(包括IntelliJ IDEA)中自动完成功能将很有效,并且您已声明并初始化了指定类型的对象。

详细了解my blog

答案 1 :(得分:10)

不,你不能,即使有一种方法你也不应该。 JavaScript是一种动态类型语言。但是,对于自动完成,您可以使用JSDoc样式文档标记来提供某些类型指针:

var Person = {
    /**
     * Say hi
     * @param {String} name The name to say hi to
     * @return {String}
     */
    sayHi : function(name)
    {
        return 'Hi ' + name;
    }
}

如果使用它们完全取决于您的IDE。

答案 2 :(得分:6)

你看过Typescript吗?它是Microsoft的一个开源项目,允许您使用强类型进行开发,然后将代码编译为Javascript。我知道是微软,但在你解雇之前先看看。

http://www.typescriptlang.org/


编辑2017

这个场景现在有两个大玩家,Typescript(如上所述)经过战斗验证,现在被Angular 2广泛使用。如果结构和相当严格的打字,如果你正在寻找,这是你最好的选择

另一种选择是Flow(https://flow.org/)它是由Facebook开发的,并且在React中被他们大量使用。 Flow允许您仅指定要键入的文件,并且是进入IMO的较低障碍。

值得一提的是,添加类型检查会给构建过程带来相当大的复杂性 - 它需要您有一个构建过程!

答案 3 :(得分:4)

你看过Google Closure Compiler吗?

某些IDE(如Jetbrains的产品)试图了解JSDoc并提供帮助,但有时它们的注释解析器与Google Closure相冲突。然而,即使使用Closure,你也不会得到完美的强力打字。

此外,它可能有点矫枉过正,但请看Haxe

答案 4 :(得分:2)

JavaScript可识别以下类型的值:

数字:例如42或3.14159

逻辑(布尔):值为true或false

字符串:例如“你好!”

null :表示空值的特殊关键字; null也是原始值。由于JavaScript区分大小写,因此null与Null,NULL或任何其他变体

不同

undefined :一个顶级属性,其值未定义; undefined也是一个原始值。

整数和实数值之间没有明确的区别 [...]

JavaScript是一种动态类型语言。这意味着您在声明变量时不必指定变量的数据类型,并且在脚本执行期间根据需要自动转换数据类型

来自https://developer.mozilla.org/en/JavaScript/Guide/Values%2C_Variables%2C_and_Literals

所以,不,你不能在JavaScript中使用强类型

答案 5 :(得分:0)

不,你不能; javascript是一种弱类型语言。这意味着JavaScript将确定您拥有的数据类型。

答案 6 :(得分:0)

您可以实现一个系统,该系统使用功能中的包装器自动处理类型检查

  

使用这种方法,您可以构建完整的declarative type check system来为您管理类型检查。   如果您有兴趣更深入地了解这个概念,请查看Functyped library

以下实现以简单但可操作的方式说明了主要思想:

/*
 * checkType() : Test the type of the value. If succeds return true, 
 * if fails, throw an Error
 */
function checkType(value,type, i){
  // perform the appropiate test to the passed 
  // value according to the provided type
  switch(type){
    case Boolean : 
      if(typeof value === 'boolean') return true;
      break;
    case String : 
      if(typeof value === 'string') return true;
      break;
    case Number : 
      if(typeof value === 'number') return true;
      break;
    default :
      throw new Error(`TypeError : Unknown type provided in argument ${i+1}`);
  }
  // test didn't succeed , throw error
  throw new Error(`TypeError : Expecting a ${type.name} in argument ${i+1}`);
}


/*
 * typedFunction() : Constructor that returns a wrapper
 * to handle each function call, performing automatic 
 * arguments type checking
 */
function typedFunction( parameterTypes, func ){
  // types definitions and function parameters 
  // count must match
  if(parameterTypes.length !== func.length) throw new Error(`Function has ${func.length} arguments, but type definition has ${parameterTypes.length}`);
  // return the wrapper...
  return function(...args){
    // provided arguments count must match types
    // definitions count
    if(parameterTypes.length !== args.length) throw new Error(`Function expects ${func.length} arguments, instead ${args.length} found.`);
    // iterate each argument value, and perform a
    // type check against it, using the type definitions
    // provided in the construction stage
    for(let i=0; i<args.length;i++) checkType( args[i], parameterTypes[i] , i)
    // if no error has been thrown, type check succeed
    // execute function!
    return func(...args);
  }
}

// Play time! 
// Declare a function that expects 2 Numbers
let myFunc = typedFunction( [ Number, Number ],  (a,b)=>{
  return a+b;
});

// call the function, with an invalid second argument
myFunc(123, '456')
// ERROR! Uncaught Error: TypeError : Expecting a Number in argument 2

答案 7 :(得分:0)

您应该考虑使用Google Closure编译器中的“ ADVANCED_OPTIMIZATIONS”来编译您的工作,它将对您的参数或变量进行类型检查。

Annotating JavaScript for the Closure Compiler: Type Expressions

示例数据类型:布尔值,窗口,goog.ui.Menu,字符串,数字

这里是声明变量及其数据类型的示例。如果尝试将变量设置为其他数据类型,则在编译后会给您错误或警告消息。

/**
 * The message hex ID.
 * @type {string}
 */
var hexId = hexId;

这是带有可能的参数类型的类声明的示例:

/**
 * Some class, initialized with an optional value.
 * @param {Object=} opt_value Some value (optional).
 * @constructor
 */
function MyClass(opt_value) {
  /**
   * Some value.
   * @type {Object|undefined}
   */
  this.myValue = opt_value;
}

使用“ ADVANCED_OPTIMIZATIONS”可以使您编写JavaScript的方式更加正确,因为它还提供了一些链接