Jint 在.net中使用js作为脚本引擎

升级到4版的一些更改

Jint.Runtime.JavaScriptException下的
.Location.Source 改为 .Location.SourceFile

Esprima.ParserException 类型找不到了
通过调试,现在编译错误和执行错误的类型都是 JavaScriptException

这库老是做一些破坏性更新,还没有详细的更新列表

升级到3.0正式版的一些更改

jsEngine.AddModule(nsName, source);
//更改为
jsEngine.Modules.Add(nsName, source);
var ns = jsEngine.ImportModule(nsName);
//更改为
var ns = jsEngine.Modules.Import(nsName);

启用严格模式后,编译会出现一些问题,修改为

var _jsEngine = new Engine(options =>
{
options.Strict = true;//严格模式
options.Interop.Enabled = true;
options.Interop.AllowSystemReflection = true;
});
var result = _jsEngine.Evaluate(
@"
class MyClass {
constructor() {
this.myProperty = 2
this.add = (a,b) =>{return a+b;}
}
}
new MyClass()
");
Console.WriteLine(_jsEngine.GetValue( result, "myProperty"));
var fn = _jsEngine.GetValue(result, "add");
var num = _jsEngine.Invoke(fn, 1,2);
Console.WriteLine(fn);
Console.WriteLine(num);

函数类型判断
Jint.Native.Function.ScriptFunctionInstance 修改为 Jint.Native.Function.ScriptFunction

old

public class Program
{
static void CSharpMehtod(string input)
{
Console.WriteLine(input);
}
static void Main(string[] args)
{
var engine = new Engine();
//传递c#函数到js引擎
engine.SetValue("CSharpMehtod", CSharpMehtod);
engine.Execute(@"
CSharpMehtod('call from js');
let jsValue = 111
function jsFunc(a, b) {
return a + b
}
");
//从js引擎中取函数、变量
var jsValue = engine.GetValue("jsValue");
var jsFunc = engine.GetValue("jsFunc");
Console.WriteLine(jsValue);
Console.WriteLine(jsFunc.Invoke(1, 2));
Console.Read();
}
}

对象变为传递的参数

var jsArg = JsValue.FromObject(engine, new Person());

以模块方式导入使用,避免全局冲突

JsEngine.SetValue("log", (object input) => Console.WriteLine(input));
JsEngine.AddModule("user1", "export function a(){log(11)}");
JsEngine.AddModule("user2", "export function a(){log(22)}");
var ns1 = JsEngine.ImportModule("user1");
var ns2 = JsEngine.ImportModule("user2");
JsEngine.Invoke(ns1.Get("a"));
JsEngine.Invoke(ns2.Get("a"));

模块的问题
模块导入后无法更改源代码,如果需要更换源代码,只有更换模块名
这将导致内存持续叠加
经测试,将所有代码以全局函数形式保存,比较方便,只要名字不变,函数内容可以一直覆盖,不会导致内存泄露

全局替换名字法

用户代码:

其中fn2为需要导出给c#调用的函数,固定名字,需要使用let 函数名 + 箭头函数的形式操作
因为下方需要导出

let state = 1
function fn1() {
console.log(this)
state = 9
}
let fn2 = (api) => {
fn1()
fn3()
console.log(this)
return state
}
function fn3() {
console.log(this)
state = 10
}

编译后代码为

function foo() { //新函数名字
let fn2 //申明
//---------------------------------
let state = 1
function fn1() {
console.log(this)
state = 9
}
let fn2 = (api) => {
fn1()
fn3()
console.log(this)
return state
}
function fn3() {
console.log(this)
state = 10
}
//---------------------------------
return{fn2: fn2 } //导出
}
posted @   trykle  阅读(354)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示