【问题标题】:Is metaprogramming possible in Javascript?Javascript 可以进行元编程吗?
【发布时间】:2010-11-24 14:20:05
【问题描述】:

在我的日常工作中,我碰巧写了一个类似于 LINQ 表达式的链式 javascript 函数来查询 JSON 结果。

var Result = from(obj1).as("x").where("x.id=5").groupby("x.status").having(count("x.status") > 5).select("x.status");

它完美地工作并给出了预期的结果。

我想知道如果代码是这样编写的(以更易读的方式),这看起来很棒

var Result = from obj1 as x where x.status
groupby x.status having count(x.status)  > 5
select x.status;

有没有办法做到这一点??

干杯

拉梅什维尔

【问题讨论】:

  • *咳嗽* hugoware.net/Projects/jLinq *咳嗽*
  • 你可以把你的代码放在一些 HTML 标签或文本文件中。然后你就可以拥有自己的 DSL 和 Javascript...

标签: javascript metaprogramming dsl


【解决方案1】:

没有。 JavaScript 不支持这个。

但这看起来也不错:

var Result =  from(obj1)
             .as("x")
             .where("x.id=5")
             .groupby("x.status")
             .having(count("x.status") > 5)
             .select("x.status");

【讨论】:

    【解决方案2】:

    大多数人坚持尝试从他们最喜欢的语言内部进行元编程。如果语言不能很好地支持元编程,那就不行了。其他答案观察到 JavaScript 没有。

    解决这个问题的一种方法是从语言外部进行元编程,使用 program transformation tools。这样的工具可以解析源代码,并对其进行任意转换(这就是元编程所做的),然后吐出修改后的程序。

    如果您有一个可以解析任意语言的通用程序转换系统,那么您就可以在/使用您喜欢的任何语言上进行元编程。请参阅我们的DMS Software Reengineering Toolkit 了解此类工具,该工具具有强大的 C、C++、Java、C#、COBOL、PHP 和 ECMAScript 前端以及许多其他编程语言,并已用于所有这些的元编程。

    在您的情况下,您希望使用 SQL 查询的新语法扩展 JavaScript 语法,然后将它们转换为纯 JavaScript。 (这很像有意编程) DMS 将轻松让您构建带有附加规则的 JavaScript 方言,然后您可以使用其程序转换功能生成等效的标准 Javascript。

    话虽如此,我不是“地球上每个程序员的自定义语法”的忠实拥护者,这是故意编程导致恕我直言的地方。

    如果有大量用户认为这很有价值,这是一件好事。这个想法可能是也可能不是其中之一;问题的一部分是你不做实验就无法找到答案,而且它可能无法获得足够的社会吸引力。

    【讨论】:

      【解决方案3】:

      虽然不是你想要的,但是可以用 javascript 编写解析器,只解析查询(存储为字符串)然后执行它。例如,使用 http://jscc.jmksf.com/ 之类的库(毫无疑问还有其他库),实现起来应该不会太难。

      但是您在问题中的内容看起来已经很棒了,我不确定您为什么希望它看起来像您建议的那样。

      【讨论】:

      • 感谢Chii 的回复。实际上我只是在尝试不同的可能性。我有 c# 背景,最近从 javascript 开始,只是想探索 JS 功能......这就是原因......感谢链接......我已经像你提到的那样环顾了 JS 解析器......和我发现codeplex.com/jsinq 很有用.. 再次感谢..
      【解决方案4】:

      考虑到这个问题是几年前提出的,我会根据当前的技术尝试添加更多内容。

      从 ECMAScript 6 开始,现在通过 SymbolReflectProxy 对象在某种意义上支持元编程。

      通过网络搜索,我发现了一系列关于这个主题的非常有趣的文章,由 Keith Kirkel 撰写:

      Metaprogramming in ES6: Symbols and why they're awesome

      简而言之,符号是可以添加到对象中的新原语(实际上不是属性),并且对于将元编程属性传递给它非常方便。符号都是关于通过修改现有类来改变它们的行为(实现中的反射)。

      Metaprogramming in ES6: Part 2 - Reflect

      简而言之,Reflect 实际上是所有这些“内部方法”的集合,这些“内部方法”只能通过 JavaScript 引擎内部实现,现在暴露在一个方便的对象中。它的用法类似于 Java 和 C# 的反射功能。它们用于发现有关您的代码的非常底层的信息(通过自省进行反射)。

      Metaprogramming in ES6: Part 3 - Proxies

      简而言之,Proxies 是处理程序对象,负责包装对象并通过陷阱(Reflection through intercession)拦截其行为。

      当然,这些对象提供了特定的元编程能力,与元编程语言相比限制性更强,但仍然可以提供方便的基本元编程方式,实际上主要是通过反射实践。

      最后,值得一提的是,在 JavaScript 中的分阶段元编程中有一些值得注意的 ongoing research work

      【讨论】:

        【解决方案5】:

        好吧,在您的代码示例中:

        var Result = from(obj1)
                    .as("x")
                    .where("x.id=5")
                    .groupby("x.status")
                    .having(count("x.status") > 5)
                    .select("x.status");
        

        我看到的唯一问题(select 用作标识符除外)是您将谓词嵌入为函数参数。你必须把它变成一个函数:

                    .having(function(x){ return x.status > 5; })
        

        JavaScript 有闭包和动态类型,所以你可以在其中做一些非常漂亮和优雅的事情。只是让你知道。

        【讨论】:

          【解决方案6】:

          在纯 JS 中你不能。但是使用正确的预处理器是可能的。

          您可以使用sweet.js 宏或(上帝原谅我)GPP 执行类似的操作。

          【讨论】:

            【解决方案7】:

            您想要的是将 javascript 解析器更改为 SQL 解析器。它不是为此而创建的,javascript 语法不允许您这样做。

            您所拥有的是 90% 像 SQL(它直接映射到它),以及 100% 有效的 javascript,这是一项了不起的成就。我对标题中问题的回答是:是的,元编程是可能的,但不,它不会给你一个 SQL 解析器,因为它必须使用 javascript 语法。

            【讨论】:

              【解决方案8】:

              如果你有 JSON 数据,也许你想要JSONPath 之类的东西。我在http://www.json.org/ 找到了这个。如果它不完全是您所需要的,那么许多其他工具都可以从那里链接到。

              (这也在处理中:http://docs.dojocampus.org/dojox/json/query

              【讨论】:

                猜你喜欢
                • 2010-09-19
                • 2010-09-11
                • 2011-02-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2013-08-27
                • 2013-07-19
                • 1970-01-01
                相关资源
                最近更新 更多