在Javascript中元编程是否可行?

问题描述 投票:15回答:8

在我的日常工作中,我碰巧编写了链接的javascript函数,类似于LINQ表达式来查询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;

有没有办法实现这个?

干杯

拉梅什嘛

javascript metaprogramming dsl
8个回答
18
投票

不,JavaScript不支持此功能。

但这看起来也很不错:

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

6
投票

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

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

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

在您的情况下,您希望使用SQL查询的新语法扩展JavaScript语法,然后将它们转换为纯JavaScript。 (这与Intentional Programming非常相似)DMS可以轻松地让您使用其他规则构建JavaScript方言,然后您可以使用其程序转换功能来生成等效的标准Javascript。

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

如果有大量用户可以发现这些有价值,那么这是一件好事。这个想法可能是也可能不是其中之一;问题的一部分是,如果不进行实验,你就无法找到答案,而且可能无法获得足够的社会牵引力。


5
投票

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

但你在问题中看到的东西看起来很棒,我不知道为什么你希望它看起来像你的建议。


3
投票

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

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具有闭包和动态类型,因此您可以在其中做一些非常漂亮和优雅的事情。只是让你知道。


3
投票

考虑到几年前问这个问题,我将尝试根据当前的技术添加更多问题。

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

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

Metaprogramming in ES6: Symbols and why they're awesome

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

Metaprogramming in ES6: Part 2 - Reflect

简而言之,Reflect实际上是所有那些“内部方法”的集合,这些“内部方法”仅通过JavaScript引擎内部提供,现在暴露在一个方便的对象中。它的用法类似于Java和C#的Reflection功能。它们用于发现有关代码的非常低级别的信息(通过内省反思)。

Metaprogramming in ES6: Part 3 - Proxies

简而言之,Proxies是处理程序对象,负责包装对象并通过陷阱拦截它们的行为(通过代祷反射)。

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

最后,值得一提的是,有一些值得注意的ongoing research work在JavaScript上进行元编程。


2
投票

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

你可以用sweet.js宏或(上帝原谅我)GPP做类似的事情。


1
投票

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

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


0
投票

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

(这也正在进行中:http://docs.dojocampus.org/dojox/json/query

© www.soinside.com 2019 - 2024. All rights reserved.