简体   繁体   English

V8Engine.Execute返回'undefined',而Microsoft.JScript的eval返回一个值

[英]V8Engine.Execute returns 'undefined', whereas Microsoft.JScript's eval returns a value

I am looking to replace the Microsoft.JScript engine in our C#.NET 4.0 program with a V8.Net engine in order to be able to execute passed in javascript functions. 我期待以取代Microsoft.JScript与引擎在我们的C#.NET 4.0程序V8.Net引擎,以便能在JavaScript函数来执行传递。 The program runs fine and correctly executes a number of scripts until it hits the following; 程序运行正常并正确执行许多脚本,直到它达到以下目的;

const t_sch_ohd = 0.1;
const t_fn = 8.302;
const t_byte = 0.04307;

var n_byte = Lookup.IndexedMsgSize (1);

var t_total = t_fn + (n_byte * t_byte) + t_sch_ohd;

The V8Engine.Execute command returns undefined , whereas our Microsoft.JScript implementation returns 9.091119999999998 which I'm not sure is correct either. V8Engine.Execute命令返回undefined ,而我们的Microsoft.JScript实现返回9.091119999999998 ,我也不确定是否正确。 I get the feeling this is something to do with how each engine handles what is considered an 'output' at the end of executing the script but I'm not sure. 我觉得这与每个引擎如何在执行脚本结束时处理被视为“输出”的事情有关,但我不确定。

Lookup.IndexesMsgSize is a function we have defined in our C#.NET application, and is consistent through both versions, I believe it returns 16 in this instance; Lookup.IndexesMsgSize是我们在C#.NET应用程序中定义的函数,并且在两个版本中都是一致的,我相信它在这个实例中返回16 ;

public uint IndexedMsgSize(uint mIndex)
{
    // only intended for MsgProcess_Fn
    if (m_message == null)
    {
        if (m_function == null)
        {
            throw new RaceException("Function reference not specified for Lookup.IndexedMsgSize");
        }
        uint count = (uint)m_function.RelatedMessagesByUDC[((int)mIndex) - 1].MessageLength;
        return count;
    }
    else
    {
        throw new RaceException("message reference not allowed for Lookup.IndexedMsgSize");
    }
}

The implementation for the Microsoft.JScript evaluation is as follows; Microsoft.JScript评估的实现如下;

public string Execute(string script)
{
    string result = "";

    try
    {
        //  EVALUATE THE SCRIPT                                 
        result = Evaluator.Eval(script);
        //using (var engine = new ScriptEngine("jscript"))
        //{
        //    ParsedScript parsed =
        //        engine.Parse("function MyFunc(x){return eval(x,'unsafe')}");
        //    engine.SetNamedItem("Lookup", m_lookup);
        //    result = parsed.CallMethod("MyFunc", script).ToString();
        //}
    }
    catch (Exception ex)
    {
        // JScript error?
        if (ex.Source.CompareTo("Microsoft.JScript") == 0)
        {
            // Yes, turn it into a Race JScript Exception to avoid a stack trace dump.
            throw new RaceScriptException(ex as JScriptException);
        }
        // Not a JScript error, so just re-throw exception.
        throw ex;
    }

    return result;
}

Evaluator is a class defined through a .dll, the Eval function is as follows in Javascript; Evaluator是一个通过.dll定义的类, Eval函数在Javascript中如下;

static function Eval(expression : String) : String {
        return eval(expression,'unsafe');
}

And In our V8.Net Implementation we simply use the built in V8Engine.Execute command; 在我们的V8.Net实现中,我们只使用内置的V8Engine.Execute命令;

public string Execute(string script)
{
    string result = "";

    try
    {
        //  EVALUATE THE SCRIPT

        //Create the V8.Net Engine                  
        V8Engine e = new V8Engine();
        //Set the Lookup instance as a global object so that the JS code in the V8.Net wrapper can access it
        e.GlobalObject.SetProperty("Lookup", m_lookup, null, true, ScriptMemberSecurity.Permanent);
        //Execute the script
        result = e.Execute(script);

        //Deprecated code:
        //result = Evaluator.Eval(script);
        //using (var engine = new ScriptEngine("jscript"))
        //{
        //    ParsedScript parsed =
        //        engine.Parse("function MyFunc(x){return eval(x,'unsafe')}");
        //    engine.SetNamedItem("Lookup", m_lookup);
        //    result = parsed.CallMethod("MyFunc", script).ToString();
        //}
    }
    catch (Exception ex)
    {
        // V8.NET error?
        if (ex.Source.CompareTo("V8.Net") == 0)
        {
            // Yes, turn it into a Race V8 Exception to avoid a stack trace dump.
            throw (V8Exception)ex;
        }
        // Not a V8 error, so just re-throw exception.
        throw ex;
    }

    return result;
}

I hope someone can shed some light on why the above results are happening, 我希望有人能说清楚为什么会出现上述结果,

Thanks in advance! 提前致谢!

JS engine uses eval function when you pass script to it. 将脚本传递给它时,JS引擎使用eval函数。 In turn, undefined is correct result of your script execution, because eval() returns the value of the last expression evaluated MDN eval docs 反过来, undefined是脚本执行的正确结果,因为eval() returns the value of the last expression evaluated MDN eval docs

In your code: 在你的代码中:

var t_total = t_fn + (n_byte * t_byte) + t_sch_ohd;

Variable Statement is the last executed expression. 变量语句是最后执行的表达式。 And it always returns undefined . 它总是返回undefined

A variable statement declares variables that are created as defined in 10.5. 变量语句声明按10.5中定义创建的变量。 Variables are initialised to undefined when created. 变量在创建时初始化为未定义。 A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created. 具有Initialiser的变量在执行VariableStatement时被赋予其AssignmentExpression的值,而不是在创建变量时。

In your case t_fn + (n_byte * t_byte) + t_sch_ohd; 在你的情况下t_fn + (n_byte * t_byte) + t_sch_ohd; is AssignmentExpression initialiser. 是AssignmentExpression初始化程序。 VariableStatement -> AssignmentExpression;

So, your code folows: 所以,你的代码如下:

  1. Perform AssignmentExpression 执行AssignmentExpression
  2. Perform VariableStatement 执行VariableStatement

There couple of ways to overcome your problem: 有几种方法可以解决您的问题:

  • Implicitly define variable: 隐式定义变量:
t_total = t_fn + (n_byte * t_byte) + t_sch_ohd;
  • Return the result explicitly by: 显式返回结果:
var t_total = t_fn + (n_byte * t_byte) + t_sch_ohd;
t_total;
  • Define variable explicitly, but above: 明确定义变量,但在上面:
var t_total;
t_total = t_fn + (n_byte * t_byte) + t_sch_ohd;

Microsoft.JScript works as you expects just due to misbehaviour. 由于不当行为, Microsoft.JScript正如您所期望的那样工作。

For deep understanding of JS nature look through http://es5.github.io/ 通过http://es5.github.io/了解JS自然的深刻理解

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM