【问题标题】:Typesafe Javascript类型安全的 Javascript
【发布时间】:2011-10-26 09:39:54
【问题描述】:

有没有办法在 JavaScript 中强制执行类型?我正在考虑一个预处理器,它接受一个用 ActionScript 3 或 Java 编写的输入文件并将其转换为 JS。

我不需要一个大的运行时设备,我只需要在我的工作流程中引入编译时的概念,并对我的代码运行微不足道的编译时检查(并且还使用接口)。我不需要来自 Java 或 Flex 的 API,只需要语法。

也可以对照 IDL 定义检查标准浏览器功能,但这不是必须的。

【问题讨论】:

  • 你所说的类型是指变量类型?因为使用typeof(variable) 很容易做到这一点。
  • 您可以使用===!== 强制执行“类型安全相等检查”。
  • 感谢您的想法,我知道可以手动检查 JS 中的类型,我只是不想这样做。
  • 对于编译时类型验证,需要生成 JavaScript(因为 JavaScript 只允许您进行运行时检查)。这很可能成为大型 JavaScript 项目的常态。

标签: javascript compiler-construction interface type-safety


【解决方案1】:

虽然我参加这个聚会有点晚了,但我认为绝对值得一提的是Dart(Google 产品)和TypeScript(Microsoft 产品)。

随着应用程序越来越基于 Web,JavaScript 正迅速成为一种非常流行的语言。但是,正如您所指出的,JavaScript 缺乏类型安全性,仅举几例;类、接口和包/命名空间/模块。

这就是 Dart 和 TypeScript 介入的地方。这些语言本质上是 JavaScript 的超集。当您编写 Dart 或 TypeScript 代码时,它会被编译成干净、符合标准的 JavaScript。

Dart 和 TypeScript 的优势在于它们提供类型安全、接口、类等。因此,您可以编写更清晰、可扩展、可管理的应用程序,这些应用程序仍可在浏览器中运行。

作为一名面向 Microsoft 的程序员,我在 TypeScript 方面拥有丰富的经验,包括积极参与该语言的开发(您可以在 codeplex 找到有关 TypeScript 开发的信息)

目前我唯一担心的是 TypeScript 缺少一些基本功能。当前的一些实现(0.9.0 alpha)似乎有一些同样巨大的漏洞,可能会阻止精明的开发人员目前使用它(当然可能会发生变化)。

我无法对 Dart 发表评论,因为我只使用过几次,但我对 Dart 的总体体验很好!

【讨论】:

    【解决方案2】:

    你应该看看haxe project

    Haxe 是一种非常好的类型化语言,它使用类型推断(即您不必编写大量类型声明),但在编译时强制类型正确性。

    该语言具有类似 javascript 的语法,编译器可以为 neko 虚拟机、javascript、as3、c++ 或 PHP 生成代码。

    更新

    今天最流行的选择可能是Typescript,它是 Javascript 的超集,它允许在编译时强制执行可选类型声明。

    【讨论】:

    • 太棒了!这正是我梦寐以求的:)
    【解决方案3】:

    GWT 可以满足您的需求,但在大多数情况下它的尺寸过大。你可以看看 googles closure 框架,它用anotations 伪造了打字保险箱

    【讨论】:

    • 谢谢,闭包绝对是朝着正确方向迈出的一步,但是作为一个 JS2JS 编译器,它迫使我使用那些超级笨拙的注释。我承认如果 JS 是唯一知道的语言,这很有用,但恕我直言,使用 Java 或 AS3 将是正确的方法
    【解决方案4】:

    有许多静态类型语言的设计都是为了特定目标编译成JavaScript(所谓的汇编网络):

    【讨论】:

      【解决方案5】:

      虽然typeof 将为每个对象或数组返回'object',但您可以使用instanceof 语句。假设您有一个类Person,并且想查看传递给您的函数的对象是否是Person,您可以这样做:

      function someFunc(person){
        if(! person instanceof Person)
          throw('argument needs to be an instance of Person.');
      
        /* ... do your stuff ... */
      }
      

      如果你只是想确保一个变量是数字 3 而不是字符串 '3',你只需要使用 === 而不是 ==

      if( var === 3 ){
        /* ... do your stuff ... */
      }
      

      【讨论】:

      • 谢谢,但问题的关键是我希望这些事情自动化。使用=== 的开销并不大,但运行时检查仅在与单元测试结合使用时才有用,即使如此,也不能保证在测试期间对函数的每个调用都已运行。
      【解决方案6】:

      我同意 Javascript 是一门漂亮的语言,但也有一些明显的漏洞,其中最糟糕且最不引人注目的是缺少静态类型安全。

      正如 eskimoblood 所指出的,GWT 和 Closure 的形式有一些折中的方法,但 正确 答案是 imo,它是 Scala,它将 Javascript 的灵活性和表达能力与类型系统结合得非常好比 Java 更好——或者 是正确的答案,只是 Scala-GWT 项目似乎陷入了困境。

      现在,我们等待......

      【讨论】:

        【解决方案7】:

        Infernu 是 JavaScript 的类型安全子集。它不会编译成 JavaScript - 它可以在您的浏览器中按原样运行!类型检查器支持完整的类型推断,因此不需要类型注释(将来它们将支持文档和结构相同类型之间的故意区分)。它尚未准备好使用,但正在进行中。

        【讨论】:

          【解决方案8】:

          这是一个用于 nodejs/浏览器的轻量级类型安全函数包装器:

          https://www.npmjs.com/package/typeshave

          它的 3.9K 压缩包,支持 jsonschema,几乎可以在任何地方使用。所以:

          foo = function(bar){
          
          }
          

          可以这样改写:

          foo = typesafe({ 
            bar: { type: "object" } 
          }, function(bar){
          
          }
          

          或者只是稍后包装,包括验证深层结构和可选参数:

          foo = typesafe({
            bar: { 
              type: "object", 
              required: true,
              properties: {
                foo: { type: "string", required:true },
                items: [{
                  type: "integer"  
                }]
              }
            }
          }, foo ); 
          
          foo({ foo: "helloworld", items:[1,2,3] });
          

          在 coffeescript imho 中看起来不那么嘈杂

          【讨论】:

            猜你喜欢
            • 2012-12-20
            • 1970-01-01
            • 1970-01-01
            • 2015-08-12
            • 2018-10-06
            • 1970-01-01
            • 2012-10-15
            • 2012-10-31
            • 2020-04-29
            相关资源
            最近更新 更多