【问题标题】:preprocessor to replace javascript keywords预处理器替换 javascript 关键字
【发布时间】:2014-09-07 04:25:40
【问题描述】:

我使用的是Angular version of the $q library,但这也适用于original q library

使用示例:

$q
  .when(someFunction)
  .then(function(){
    // ..
  })
  .catch(function(){
    // ..
  })
  .finally(function(){
    // ..
  });

很遗憾,某些函数名称(例如 finally)与 javascript 关键字冲突。
来自 Angular 参考:

"由于 finally 是 JavaScript 中的保留字,并且 ES3 不支持保留关键​​字作为属性名称,因此您需要调用 promise['finally'](callback) 之类的方法 让你的代码 IE8 和 Android 2.x 兼容。”

ECMA-262,官方标准,可在http://www.ecma-international.org/publications/standards/Ecma-262.htm 获得,声明:

7.6.1.1 关键字

以下标记是 ECMAScript 关键字,可能用作 ECMAScript 程序中的标识符。

break           do              instanceof      typeof  
case            else            new             var 
catch           finally         return          void 
continue        for             switch          while 
debugger        function        this            with 
default         if              throw            
delete          in              try

这意味着必须将第一个示例更改为以下代码才能使其与 IE8 一起使用:

$q
  .when(someFunction)
  .then(function(){
    // ..
  })
  ['catch'](function(){
    // ..
  })
  ['finally'](function(){
    // ..
  });

由于这段代码更难维护,我正在寻找一个 javascript 预处理器(可能是一个繁重的任务),它将第一个示例转换为 IE8 兼容版本。

有这样的预处理器吗?

【问题讨论】:

  • 我不知道有哪一个。您可能必须自己实现。
  • @RevanProdigalKnight 你知道有源地图支持的好参考项目吗?
  • 不幸的是,并非如此。当我实现C-style preprocessor 时,我没有使用源映射。
  • 使用 esprima 和 escodegen 实际上很容易做到这一点。
  • 附带说明,在原始 q 库中,可以使用 fin 代替 finallyfail 代替 catch

标签: javascript


【解决方案1】:

几个月前,您友好的邻居 Stef Panner 就为此创建了这样一个工具。它被称为es3-safe-recast。还有一个grunt task

让我们来看看它的作用。首先,它需要用于 JS 语法树分析的 Esprima 包,并在其之上重铸为这些转换而构建的包:

'use strict';
var esprima = require('esprima');
var recast = require('recast');
var Visitor = recast.Visitor;
var types = recast.types;
var namedTypes = types.namedTypes;
var builders = types.builders;

然后它包含所有标识符的大图 - 就像您的列表一样:

identifierToLiteral.finally = true; // here is `finally` for example

这是它如何解析树并将其替换为访问者:

var ES6Safe = Visitor.extend({
  visitProperty: function(node) { // go through all properties
    // check if need to replace name with literal
    if (namedTypes.Identifier.check(node.key) && identifierToLiteral[node.key.name]) {
      node.key = builders.literal(node.key.name);
    }

    return this.genericVisit(node);
  },

  visitMemberExpression: function(node) { // and all member expressions
    var property = node.property;
    var newNode;
    // check if need to replace name with literal
    if (namedTypes.Identifier.check(property) && identifierToLiteral[property.name]) {
      newNode = builders.memberExpression(node.object, builders.literal(property.name), true);
    } else {
      newNode = node;
    }
    return this.genericVisit(newNode);
  }
});

最后通过recast运行代码:

ast = recast.parse(source, { esprima: esprima } );
new ES6Safe().visit(ast);
code = recast.print(ast).code;

生成上述代码的安全版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    相关资源
    最近更新 更多