2009-09-01 75 views
14

在我的日常工作中,我碰巧寫了鏈式JavaScript函數,它像LINQ表達式來查詢JSON結果。是否可以在Javascript中進行元編程?

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; 

是有辦法做到這一點?

乾杯

拉梅什VEL

+4

\ *咳嗽* * http://www.hugoware.net/Projects/jLinq \ *咳嗽* * – 2010-07-20 02:04:03

+0

你可以把你的代碼放在一些HTML標記或文本文件中。然後,你可以有你自己的DSL與Javascript ... – Philip 2010-11-18 14:13:21

回答

17

號JavaScript不支持此功能。

但是,這看起來相當不錯過:

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

雖然不大,你想要的東西,就可以使用JavaScript編寫解析器,只是解析查詢(存儲爲字符串),然後執行它。例如,使用像http://jscc.jmksf.com/這樣的庫(毫無疑問,那裏有其他的),它實現起來應該太難了。

但是你在這個問題上看起來已經很棒了,我不確定你爲什麼希望它看起來像你的建議。

+0

感謝您的答覆Chii ..其實我只是試驗不同的可能性。我用c#背景,latestlty在JavaScript中開始,只是想探索JS的功能...多數民衆贊成的原因..多謝鏈接..我已經看過像你提到的JS解析器..和我發現http://www.codeplex.com/jsinq是有用的..再次感謝.. – RameshVel 2009-09-01 10:52:30

1

Wat你想要的是將JavaScript解析器更改爲SQL解析器。它並沒有被創建,JavaScript語法不允許你。

你有什麼像SQL(它直接映射到它)90%,和100%的有效JavaScript,這是一個偉大的成就。我在標題中回答的問題是:是的,元編程是可能的,但是它不會給你一個SQL解析器,因爲它必然會使用JavaScript語法。

6

大多數人堅持嘗試從元程序裏面他們最喜歡的語言。如果語言不能很好地支持元編程,那就行不通了;其他答案已經觀察到JavaScript沒有。

解決的辦法是從做元編程之外的語言,使用 program transformation tools。這些工具可以解析源代碼,並對其進行任意轉換(這就是元編程無論如何),然後吐出修改過的程序。

如果您有一個通用的程序轉換系統,可以解析任意語言,那麼您可以使用任何您喜歡的語言進行元編程。請參閱我們的DMS Software Reengineering Toolkit,該工具具有用於C,C++,Java,C#,COBOL,PHP和ECMAScript以及許多其他編程語言的健壯前端,並且已用於所有這些元編程。

對於您的情況,您希望使用SQL語法的新語法擴展JavaScript語法,然後將它們轉換爲純JavaScript。 (這與意圖編程很相似) DMS可以輕鬆讓您使用附加規則構建JavaScript方言,然後您可以使用其程序轉換功能來生成等效的標準Javascript。儘管如此,我並不是「地球上每個程序員的自定義語法」的熱衷者,這是故意編程導致恕我直言的地方。

如果有大量的用戶會發現這種有價值的東西,這是一件好事。這個想法可能是也可能不是其中之一;問題的一部分是你沒有做實驗就沒有找到答案,並且可能無法獲得足夠的社會影響力。

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有閉包和動態打字,所以你可以做一些非常漂亮和優雅的東西。只是讓你知道。

+0

感謝喬伊,這是一個好主意.. :) – RameshVel 2010-07-20 04:52:46

2

在純JS不,你不能。但有了正確的預處理器,這是可能的。

你可以用類似sweet.js的宏或(神原諒我)GPP

1

考慮到幾年前提出這個問題,我會嘗試在現有技術的基礎上增加更多。

從ECMAScript 6起,現在通過SymbolReflectProxy對象支持元編程。

通過在網絡上搜索,我發現了一系列關於這個問題很有趣的文章,由Keith基爾克爾寫:

Metaprogramming in ES6: Symbols and why they're awesome

總之,符號是可以在對象內增加新的原語(實際上沒有屬性),並且非常方便將元編程屬性傳遞給它。符號都是關於通過修改現有類的行爲(實現中的反射)來改變它們的行爲。

Metaprogramming in ES6: Part 2 - Reflect

總之,體現的是有效地所有這些都是獨家提供通過JavaScript引擎內部,現在暴露在一個單一的,方便的對象那些「內部方法」的集合。它的用法類似於Java和C#的Reflection功能。它們被用來發現關於你的代碼的非常低層次的信息(通過自省進行反思)。

Metaprogramming in ES6: Part 3 - Proxies

總之,代理是處理對象,負責包裝的對象,並通過陷阱攔截他們的行爲(通過調解反射)。實際上,這些對象提供了特定的元編程功能,與元編程語言相比,限制性更強,但仍然可以提供基本元編程的便捷方式,主要是通過反射實踐。

最後,值得一提的是,有一些值得注意的ongoing research work在JavaScript中的階段元編程。

相關問題