有趣的Javascript Engine–V8Sharp
昨天一個朋友介紹我一個新奇有趣又好玩的東西 v8sharp
這是一個javascript的引擎,可以讓我們在本機端或Server端編譯JS
進而可以直接使用JS內的function。
整理一下腦袋:
剛接觸時覺得腦袋有些混亂,因為本能覺得Javascript是Client端的語言,
但在使用V8Engine時,都是在本機執行的,所以請想成可以在本機混和
使用Javascript以及C#這兩種語言。
使用上很簡單,只要記得幾個步驟:
- 取得V8Engine物件
- 註冊C#的Class(如果沒有要使用可以不用)
- Compile一段Javascript
- 執行,取得JS funtion的結果
以下程式用 ASP.NET MVC 示範
範例一
public ActionResult Index()
{
//取得V8Engine
V8Engine engine = V8Engine.Create();
//寫一段JS的function,名字叫"Welcome",可以傳一個參數
V8Script script = engine.Compile(@"function Welcome(name){
return 'Welcome my Blog - '+ name ;
}"
);
//由於上面的JS只是一個function,如果要使用,必須先執行一次
engine.Execute(script);
//這邊就是呼叫上方的JS function "Welcome",並傳入"CodingRoad"這個字串
object result = engine.Execute("Welcome('CodingRoad')");
//將結果用ViewData傳到View上
ViewData["Result"] = result.ToString();
return View();
}
上面的範例是在c#中呼叫一段簡單的JS function,然後將傳回的字串寫到View上
結果
範例二
public ActionResult About()
{
V8Engine engine = V8Engine.Create();
MyClass my = new MyClass();
//註冊一個C#的物件,第一個參數名稱可以自己取名,第二個參數是new出的物件
//共有七種多載可選
engine.Register("CSharpClass", my);
//用Execute的另一個多載,直接傳入JS function,
//並在function中呼叫C#類別MyClass的方法GetChineseDate
//傳回民國日期
var result = engine.Execute(@"function ShowDate(){
return CSharpClass.GetChineseDate(); //這邊呼叫了自己寫的C#的方法
}
ShowDate();
");
ViewData["Date"] = result.ToString();
return View();
}
public class MyClass
{
public string GetChineseDate()
{
CultureInfo info = new CultureInfo("zh-TW");
TaiwanCalendar calendar = new TaiwanCalendar();
info.DateTimeFormat.Calendar = calendar;
return DateTime.Now.ToString("yyy-MM-dd", info);
}
}
這個範例先註冊了我自己寫的C#的類別,然後再JS中呼叫了GetChineseDate方法
然後執行後將結果傳到View上。
結果
範例三
public ActionResult DiscountPrice()
{
V8Engine engine = V8Engine.Create();
//自己寫了一個Extension Method,讀取指定路徑的js
engine.RegisterFormJsPath(Server.MapPath("~/App_Data/V8UseScript.js"));
//執行js內的function
var result=engine.Execute("Discount(3500)");
ViewData["Price"] = result.ToString();
return View();
}
Extension Method
public static class V8SharpExtension
{
public static object RegisterFormJsPath(this V8Engine engine, string path)
{
string script = File.ReadAllText(path);
return engine.Execute(script);
}
}
V8UseScript.js
function Discount(value) {
var result = parseFloat(value) * 0.8;
return Math.round(result);
}
這個範例用了我寫的extension method,讀取App_Data內的V8UseScript.js檔
JS內是一個Discount的function,傳入一個參數,打八折後傳回。
結果
使用上大概是這個樣子
想想我們可以在程式中留一個洞
例如範例三的Discount,然後因應不同的折扣活動,寫不同的JS Function
只要更新JS檔,就可以更改需求,不需要重新編譯。
比起用Reflection抽換dll,或是用Expression寫動態的語法來達成不重新編譯
而更改需求的效果,用JS對大部分的人來說還是比較熟悉的。
而且還可以選擇兩種語法的優點來選擇要用哪種寫,實在是很好玩又方便的東西。