使用C#解析并运行JavaScript代码

如果想在C#编程中解析并运行JavaScript代码,常见的方式有两种:

  1. 利用COM组件“Microsoft Script Control”,可参见:C#使用技巧之调用JS脚本方法一
  2. 利用JScript.net,可参见:C#使用技巧之调用JS脚本方法二 或 从命令行编译 JScript 代码

这两种方式都能达到在C#中执行JavaScript代码的效果,不过各有利弊。 方法一对程序运行环境有要求,程序只能以x86为目标平台。方法二实际是将JavaScript代码编译成为了.NET程序集,对JavaScript代码有严格的格式要求,但是可以在任意平台发布(支持跨平台)。 除此之外,其实还有另一种方法来实现这个功能,兼容x86和x64平台,不过仅限于在Windows下使用。而且对JavaScript代码没有严格的格式要求。

Windows Script Engines

Microsoft® Windows® Script Interfaces introduce a new way for an application to add scripting and OLE Automation capabilities. With the advent of the interfaces, hosts can call upon disparate scripting engines from multiple sources and vendors to perform scripting between components. The implementation of the script itself—language, syntax, persistent format, execution model, and so on—is left to the script vendor. The designers have taken care to allow hosts that rely on Windows Script to use arbitrary language back ends.

以上是微软对Windows Script Engines的官方解释,详细信息可以参看:Microsoft Windows Script Interfaces - Introduction。简单的说,Windows Script Engines 提供了一种新的方式,让我们可以为应用程序添加脚本功能。 所以我们只需要将Windows Script Engines进行包装即可。

调用示例

1、直接执行表达式:

Console.WriteLine(ScriptEngine.Eval("jscript", "1+2/3"));

将会输出:1.66666666666667

2、调用有参数的方法:

using (ScriptEngine engine = new ScriptEngine("jscript"))
{
  ParsedScript parsed = engine.Parse("function MyFunc(x){return 1+2+x}");
  Console.WriteLine(parsed.CallMethod("MyFunc", 3));
}

将会输出:6

3、调用可选参数NameItem方法:

using (ScriptEngine engine = new ScriptEngine("jscript"))
{
    ParsedScript parsed = engine.Parse("function MyFunc(x){return 1+2+x+My.Num}");
    MyItem item = new MyItem();
    item.Num = 4;
    engine.SetNamedItem("My", item);
    Console.WriteLine(parsed.CallMethod("MyFunc", 3));
}

[ComVisible(true)] // Script engines are COM components.
public class MyItem
{
    public int Num { get; set; }
}

将会输出:10

如果宿主服务中安装有IE9+的浏览器,那么我们可以调用更快的JavaScript引擎"chakra":

using (ScriptEngine engine = new ScriptEngine("{16d51579-a30b-4c8b-a276-0ff4dc41e755}"))
{
    // continue with chakra now
}

ScriptEngine.cs

上面只是部分的调用示例,但是应该可以满足80%的业务需求。上面的代码依赖于ScriptEngine类,完整的ScriptEngine.cs代码如下:

/// <summary>
/// Represents a Windows Script Engine such as JScript, VBScript, etc.
/// </summary>
public sealed class ScriptEngine : IDisposable
{
    /// <summary>
    /// The name of the function used for simple evaluation.
    /// </summary>
    public const string MethodName = "EvalMethod";

    /// <summary>
    /// The default scripting language name.
    /// </summary>
    public const string DefaultLanguage = JavaScriptLanguage;

    /// <summary>
    /// The JavaScript or jscript scripting language name.
    /// </summary>
    public const string JavaScriptLanguage = "javascript";

    /// <summary>
    /// The javascript or jscript scripting language name.
    /// </summary>
    public const string VBScriptLanguage = "vbscript";

    /// <summary>
    /// The chakra javascript engine CLSID. The value is {16d51579-a30b-4c8b-a276-0ff4dc41e755}.
    /// </summary>
    public const string ChakraClsid = "{16d51579-a30b-4c8b-a276-0ff4dc41e755}";

    private IActiveScript _engine;
    private IActiveScriptParse32 _parse32;
    private IActiveScriptParse64 _parse64;
    internal ScriptSite Site;
    private Version _version;
    private string _name;

    [Guid("BB1A2AE1-A4F9-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScript
    {
        [PreserveSig]
        int SetScriptSite(IActiveScriptSite pass);
        [PreserveSig]
        int GetScriptSite(Guid riid, out IntPtr site);
        [PreserveSig]
        int SetScriptState(ScriptState state);
        [PreserveSig]
        int GetScriptState(out ScriptState scriptState);
        [PreserveSig]
        int Close();
        [PreserveSig]
        int AddNamedItem(string name, ScriptItem flags);
        [PreserveSig]
        int AddTypeLib(Guid typeLib, uint major, uint minor, uint flags);
        [PreserveSig]
        int GetScriptDispatch(string itemName, out IntPtr dispatch);
        [PreserveSig]
        int GetCurrentScriptThreadID(out uint thread);
        [PreserveSig]
        int GetScriptThreadID(uint win32ThreadId, out uint thread);
        [PreserveSig]
        int GetScriptThreadState(uint thread, out ScriptThreadState state);
        [PreserveSig]
        int InterruptScriptThread(uint thread, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo, uint flags);
        [PreserveSig]
        int Clone(out IActiveScript script);
    }

    [Guid("4954E0D0-FBC7-11D1-8410-006008C3FBFC"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptProperty
    {
        [PreserveSig]
        int GetProperty(int dwProperty, IntPtr pvarIndex, out object pvarValue);
        [PreserveSig]
        int SetProperty(int dwProperty, IntPtr pvarIndex, ref object pvarValue);
    }

    [Guid("DB01A1E3-A42B-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptSite
    {
        [PreserveSig]
        int GetLCID(out int lcid);
        [PreserveSig]
        int GetItemInfo(string name, ScriptInfo returnMask, out IntPtr item, IntPtr typeInfo);
        [PreserveSig]
        int GetDocVersionString(out string version);
        [PreserveSig]
        int OnScriptTerminate(object result, System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int OnStateChange(ScriptState scriptState);
        [PreserveSig]
        int OnScriptError(IActiveScriptError scriptError);
        [PreserveSig]
        int OnEnterScript();
        [PreserveSig]
        int OnLeaveScript();
    }

    [Guid("EAE1BA61-A4ED-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptError
    {
        [PreserveSig]
        int GetExceptionInfo(out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int GetSourcePosition(out uint sourceContext, out int lineNumber, out int characterPosition);
        [PreserveSig]
        int GetSourceLineText(out string sourceLine);
    }

    [Guid("BB1A2AE2-A4F9-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptParse32
    {
        [PreserveSig]
        int InitNew();
        [PreserveSig]
        int AddScriptlet(string defaultName, string code, string itemName, string subItemName, string eventName, string delimiter, IntPtr sourceContextCookie, uint startingLineNumber, ScriptText flags, out string name, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int ParseScriptText(string code, string itemName, IntPtr context, string delimiter, int sourceContextCookie, uint startingLineNumber, ScriptText flags, out object result, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
    }

    [Guid("C7EF7658-E1EE-480E-97EA-D52CB4D76D17"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IActiveScriptParse64
    {
        [PreserveSig]
        int InitNew();
        [PreserveSig]
        int AddScriptlet(string defaultName, string code, string itemName, string subItemName, string eventName, string delimiter, IntPtr sourceContextCookie, uint startingLineNumber, ScriptText flags, out string name, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
        [PreserveSig]
        int ParseScriptText(string code, string itemName, IntPtr context, string delimiter, long sourceContextCookie, uint startingLineNumber, ScriptText flags, out object result, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo);
    }

    [Flags]
    private enum ScriptText
    {
        None = 0,
        //DelayExecution = 1,
        //IsVisible = 2,
        IsExpression = 32,
        IsPersistent = 64,
        //HostManageSource = 128
    }

    [Flags]
    private enum ScriptInfo
    {
        //None = 0,
        //IUnknown = 1,
        ITypeInfo = 2
    }

    [Flags]
    private enum ScriptItem
    {
        //None = 0,
        IsVisible = 2,
        IsSource = 4,
        //GlobalMembers = 8,
        //IsPersistent = 64,
        //CodeOnly = 512,
        //NoCode = 1024
    }

    private enum ScriptThreadState
    {
        //NotInScript = 0,
        //Running = 1
    }

    private enum ScriptState
    {
        Uninitialized = 0,
        Started = 1,
        Connected = 2,
        Disconnected = 3,
        Closed = 4,
        Initialized = 5
    }

    private const int TYPE_E_ELEMENTNOTFOUND = unchecked((int)(0x8002802B));
    private const int E_NOTIMPL = -2147467263;

    /// <summary>
    /// Determines if a script engine with the input name exists.
    /// </summary>
    /// <param name="language">The language.</param>
    /// <returns>true if the engine exists; false otherwise.</returns>
    public static Version GetVersion(string language)
    {
        if (language == null)
            throw new ArgumentNullException("language");

        Type engine;
        Guid clsid;
        if (Guid.TryParse(language, out clsid))
        {
            engine = Type.GetTypeFromCLSID(clsid, false);
        }
        else
        {
            engine = Type.GetTypeFromProgID(language, false);
        }
        if (engine == null)
            return null;

        IActiveScript scriptEngine = Activator.CreateInstance(engine) as IActiveScript;
        if (scriptEngine == null)
            return null;

        IActiveScriptProperty scriptProperty = scriptEngine as IActiveScriptProperty;
        if (scriptProperty == null)
            return new Version(1, 0, 0, 0);

        int major = GetProperty(scriptProperty, SCRIPTPROP_MAJORVERSION, 0);
        int minor = GetProperty(scriptProperty, SCRIPTPROP_MINORVERSION, 0);
        int revision = GetProperty(scriptProperty, SCRIPTPROP_BUILDNUMBER, 0);
        Version version = new Version(major, minor, Environment.OSVersion.Version.Build, revision);
        Marshal.ReleaseComObject(scriptProperty);
        Marshal.ReleaseComObject(scriptEngine);
        return version;
    }

    private static T GetProperty<T>(IActiveScriptProperty prop, int index, T defaultValue)
    {
        object value;
        if (prop.GetProperty(index, IntPtr.Zero, out value) != 0)
            return defaultValue;

        try
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="ScriptEngine"/> class.
    /// </summary>
    /// <param name="language">The scripting language. Standard Windows Script engines names are ‘jscript‘ or ‘vbscript‘.</param>
    public ScriptEngine(string language)
    {
        if (language == null)
            throw new ArgumentNullException("language");

        Type engine;
        Guid clsid;
        if (Guid.TryParse(language, out clsid))
        {
            engine = Type.GetTypeFromCLSID(clsid, true);
        }
        else
        {
            engine = Type.GetTypeFromProgID(language, true);
        }
        _engine = Activator.CreateInstance(engine) as IActiveScript;
        if (_engine == null)
            throw new ArgumentException(language + " is not an Windows Script Engine", "language");

        Site = new ScriptSite();
        _engine.SetScriptSite(Site);

        // support 32-bit & 64-bit process
        if (IntPtr.Size == 4)
        {
            _parse32 = (IActiveScriptParse32)_engine;
            _parse32.InitNew();
        }
        else
        {
            _parse64 = (IActiveScriptParse64)_engine;
            _parse64.InitNew();
        }
    }

    private const int SCRIPTPROP_NAME = 0x00000000;
    private const int SCRIPTPROP_MAJORVERSION = 0x00000001;
    private const int SCRIPTPROP_MINORVERSION = 0x00000002;
    private const int SCRIPTPROP_BUILDNUMBER = 0x00000003;

    /// <summary>
    /// Gets the engine version.
    /// </summary>
    /// <value>
    /// The version.
    /// </value>
    public Version Version
    {
        get
        {
            if (_version == null)
            {
                int major = GetProperty(SCRIPTPROP_MAJORVERSION, 0);
                int minor = GetProperty(SCRIPTPROP_MINORVERSION, 0);
                int revision = GetProperty(SCRIPTPROP_BUILDNUMBER, 0);
                _version = new Version(major, minor, Environment.OSVersion.Version.Build, revision);
            }
            return _version;
        }
    }

    /// <summary>
    /// Gets the engine name.
    /// </summary>
    /// <value>
    /// The name.
    /// </value>
    public string Name
    {
        get
        {
            if (_name == null)
            {
                _name = GetProperty(SCRIPTPROP_NAME, string.Empty);
            }
            return _name;
        }
    }

    /// <summary>
    /// Gets a script engine property.
    /// </summary>
    /// <typeparam name="T">The expected property type.</typeparam>
    /// <param name="index">The property index.</param>
    /// <param name="defaultValue">The default value if not found.</param>
    /// <returns>The value of the property or the default value.</returns>
    public T GetProperty<T>(int index, T defaultValue)
    {
        object value;
        if (!TryGetProperty(index, out value))
            return defaultValue;

        try
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }
        catch
        {
            return defaultValue;
        }
    }

    /// <summary>
    /// Gets a script engine property.
    /// </summary>
    /// <param name="index">The property index.</param>
    /// <param name="value">The value.</param>
    /// <returns>true if the property was successfully got; false otherwise.</returns>
    public bool TryGetProperty(int index, out object value)
    {
        value = null;
        IActiveScriptProperty property = _engine as IActiveScriptProperty;
        if (property == null)
            return false;

        return property.GetProperty(index, IntPtr.Zero, out value) == 0;
    }

    /// <summary>
    /// Sets a script engine property.
    /// </summary>
    /// <param name="index">The property index.</param>
    /// <param name="value">The value.</param>
    /// <returns>true if the property was successfully set; false otherwise.</returns>
    public bool SetProperty(int index, object value)
    {
        IActiveScriptProperty property = _engine as IActiveScriptProperty;
        if (property == null)
            return false;

        return property.SetProperty(index, IntPtr.Zero, ref value) == 0;
    }

    /// <summary>
    /// Adds the name of a root-level item to the scripting engine‘s name space.
    /// </summary>
    /// <param name="name">The name. May not be null.</param>
    /// <param name="value">The value. It must be a ComVisible object.</param>
    public void SetNamedItem(string name, object value)
    {
        if (name == null)
            throw new ArgumentNullException("name");

        _engine.AddNamedItem(name, ScriptItem.IsVisible | ScriptItem.IsSource);
        Site.NamedItems[name] = value;
    }

    internal class ScriptSite : IActiveScriptSite
    {
        internal ScriptException LastException;
        internal Dictionary<string, object> NamedItems = new Dictionary<string, object>();

        int IActiveScriptSite.GetLCID(out int lcid)
        {
            lcid = Thread.CurrentThread.CurrentCulture.LCID;
            return 0;
        }

        int IActiveScriptSite.GetItemInfo(string name, ScriptInfo returnMask, out IntPtr item, IntPtr typeInfo)
        {
            item = IntPtr.Zero;
            if ((returnMask & ScriptInfo.ITypeInfo) == ScriptInfo.ITypeInfo)
                return E_NOTIMPL;

            object value;
            if (!NamedItems.TryGetValue(name, out value))
                return TYPE_E_ELEMENTNOTFOUND;

            item = Marshal.GetIUnknownForObject(value);
            return 0;
        }

        int IActiveScriptSite.GetDocVersionString(out string version)
        {
            version = null;
            return 0;
        }

        int IActiveScriptSite.OnScriptTerminate(object result, System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo)
        {
            return 0;
        }

        int IActiveScriptSite.OnStateChange(ScriptState scriptState)
        {
            return 0;
        }

        int IActiveScriptSite.OnScriptError(IActiveScriptError scriptError)
        {
            string sourceLine = null;
            try
            {
                scriptError.GetSourceLineText(out sourceLine);
            }
            catch
            {
                // happens sometimes...
            }
            uint sourceContext;
            int lineNumber;
            int characterPosition;
            scriptError.GetSourcePosition(out sourceContext, out lineNumber, out characterPosition);
            lineNumber++;
            characterPosition++;
            System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo;
            scriptError.GetExceptionInfo(out exceptionInfo);

            string message;
            if (!string.IsNullOrEmpty(sourceLine))
            {
                message = "Script exception: {1}. Error number {0} (0x{0:X8}): {2} at line {3}, column {4}. Source line: ‘{5}‘.";
            }
            else
            {
                message = "Script exception: {1}. Error number {0} (0x{0:X8}): {2} at line {3}, column {4}.";
            }
            LastException = new ScriptException(string.Format(message, exceptionInfo.scode, exceptionInfo.bstrSource, exceptionInfo.bstrDescription, lineNumber, characterPosition, sourceLine));
            LastException.Column = characterPosition;
            LastException.Description = exceptionInfo.bstrDescription;
            LastException.Line = lineNumber;
            LastException.Number = exceptionInfo.scode;
            LastException.Text = sourceLine;
            return 0;
        }

        int IActiveScriptSite.OnEnterScript()
        {
            LastException = null;
            return 0;
        }

        int IActiveScriptSite.OnLeaveScript()
        {
            return 0;
        }
    }

    /// <summary>
    /// Evaluates an expression using the specified language.
    /// </summary>
    /// <param name="language">The language.</param>
    /// <param name="expression">The expression. May not be null.</param>
    /// <returns>The result of the evaluation.</returns>
    public static object Eval(string language, string expression)
    {
        return Eval(language, expression, null);
    }

    /// <summary>
    /// Evaluates an expression using the specified language, with an optional array of named items.
    /// </summary>
    /// <param name="language">The language.</param>
    /// <param name="expression">The expression. May not be null.</param>
    /// <param name="namedItems">The named items array.</param>
    /// <returns>The result of the evaluation.</returns>
    public static object Eval(string language, string expression, params KeyValuePair<string, object>[] namedItems)
    {
        if (language == null)
            throw new ArgumentNullException("language");

        if (expression == null)
            throw new ArgumentNullException("expression");

        using (ScriptEngine engine = new ScriptEngine(language))
        {
            if (namedItems != null)
            {
                foreach (KeyValuePair<string, object> kvp in namedItems)
                {
                    engine.SetNamedItem(kvp.Key, kvp.Value);
                }
            }
            return engine.Eval(expression);
        }
    }

    /// <summary>
    /// Evaluates an expression.
    /// </summary>
    /// <param name="expression">The expression. May not be null.</param>
    /// <returns>The result of the evaluation.</returns>
    public object Eval(string expression)
    {
        if (expression == null)
            throw new ArgumentNullException("expression");

        return Parse(expression, true);
    }

    /// <summary>
    /// Parses the specified text and returns an object that can be used for evaluation.
    /// </summary>
    /// <param name="text">The text to parse.</param>
    /// <returns>An instance of the ParsedScript class.</returns>
    public ParsedScript Parse(string text)
    {
        if (text == null)
            throw new ArgumentNullException("text");

        return (ParsedScript)Parse(text, false);
    }

    private object Parse(string text, bool expression)
    {
        const string varName = "x___";
        object result;

        _engine.SetScriptState(ScriptState.Connected);

        ScriptText flags = ScriptText.None;
        if (expression)
        {
            flags |= ScriptText.IsExpression;
        }

        try
        {
            // immediate expression computation seems to work only for 64-bit
            // so hack something for 32-bit...
            System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo;
            if (_parse32 != null)
            {
                if (expression)
                {
                    // should work for jscript & vbscript at least...
                    text = varName + "=" + text;
                }
                _parse32.ParseScriptText(text, null, IntPtr.Zero, null, 0, 0, flags, out result, out exceptionInfo);
            }
            else
            {
                _parse64.ParseScriptText(text, null, IntPtr.Zero, null, 0, 0, flags, out result, out exceptionInfo);
            }
        }
        catch
        {
            if (Site.LastException != null)
                throw Site.LastException;

            throw;
        }

        IntPtr dispatch;
        if (expression)
        {
            // continue  our 32-bit hack...
            if (_parse32 != null)
            {
                _engine.GetScriptDispatch(null, out dispatch);
                object dp = Marshal.GetObjectForIUnknown(dispatch);
                try
                {
                    return dp.GetType().InvokeMember(varName, BindingFlags.GetProperty, null, dp, null);
                }
                catch
                {
                    if (Site.LastException != null)
                        throw Site.LastException;

                    throw;
                }
            }
            return result;
        }

        _engine.GetScriptDispatch(null, out dispatch);
        ParsedScript parsed = new ParsedScript(this, dispatch);
        return parsed;
    }

    /// <summary>
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
        if (_parse32 != null)
        {
            Marshal.ReleaseComObject(_parse32);
            _parse32 = null;
        }

        if (_parse64 != null)
        {
            Marshal.ReleaseComObject(_parse64);
            _parse64 = null;
        }

        if (_engine != null)
        {
            Marshal.ReleaseComObject(_engine);
            _engine = null;
        }
    }
}

public sealed class ParsedScript : IDisposable
{
    private object _dispatch;
    private readonly ScriptEngine _engine;

    internal ParsedScript(ScriptEngine engine, IntPtr dispatch)
    {
        _engine = engine;
        _dispatch = Marshal.GetObjectForIUnknown(dispatch);
    }

    public object CallMethod(string methodName, params object[] arguments)
    {
        if (_dispatch == null)
            throw new InvalidOperationException();

        if (methodName == null)
            throw new ArgumentNullException("methodName");

        try
        {
            return _dispatch.GetType().InvokeMember(methodName, BindingFlags.InvokeMethod, null, _dispatch, arguments);
        }
        catch
        {
            if (_engine.Site.LastException != null)
                throw _engine.Site.LastException;

            throw;
        }
    }

    void IDisposable.Dispose()
    {
        if (_dispatch != null)
        {
            Marshal.ReleaseComObject(_dispatch);
            _dispatch = null;
        }
    }
}

[Serializable]
public class ScriptException : Exception
{
    public ScriptException()
        : base("Script Exception")
    {
    }

    public ScriptException(string message)
        : base(message)
    {
    }

    public ScriptException(Exception innerException)
        : base(null, innerException)
    {
    }

    public ScriptException(string message, Exception innerException)
        : base(message, innerException)
    {
    }

    protected ScriptException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }

    public string Description { get; internal set; }
    public int Line { get; internal set; }
    public int Column { get; internal set; }
    public int Number { get; internal set; }
    public string Text { get; internal set; }
}

提示:该方法同样可以用来执行VBScript代码。

时间: 2024-11-08 23:45:00

使用C#解析并运行JavaScript代码的相关文章

浏览器地址栏运行JavaScript代码

这个很多人应该还是知道的,在浏览器地址栏可以直接运行JavaScript代码,做法是以javascript:开头后跟要执行的语句.比如: javascript:alert('hello from address bar :)'); 将以上代码贴到浏览器地址栏回车后alert正常执行,一个弹窗神现. 需要注意的是如果是通过copy paste代码到浏览器地址栏的话,IE及Chrome会自动去掉代码开头的javascript:,所以需要手动添加起来才能正确执行,而Firefox中虽然不会自动去掉,但

代码示例:一些简单技巧优化JavaScript编译器工作详解,让你写出高性能运行的更快JavaScript代码

告诉你一些简单的技巧来优化JavaScript编译器工作,从而让你的JavaScript代码运行的更快.尤其是在你游戏中发现帧率下降或是当垃圾回收器有大量的工作要完成的时候. 单一同态: 当你定义了一个两个参数的函数,编译器会接受你的定义,如果函数参数的类型.个数或者返回值的类型改变编译器的工作会变得艰难.通常情况下,单一同态的数据结构和个数相同的参数会让你的程序会更好的工作. function example(a, b) { // 期望a,b都为数值类型 console.log(++a * +

JavaScript在线运行html代码,保存html代码到本地

在网页中看到一些html代码却不知这样的代码运行起来是什么样子?觉得一些模板代码不错还要手动复制,新建文件,粘贴嫌麻烦?下面的js方法可以帮你解决这些问题. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>JavaScript在线运行html代码,保存html代码到本地</title> </head> <body> &l

在JavaScript中,运行下面代码,sum的值是()。

在JavaScript中,运行下面代码,sum的值是(). var sum=0;for(i=1;i<10;i++){if(i%5==0)break;sum=sum+i;} A. 40B. 50C. 5D. 10 答案:http://hovertree.com/shortanswer/bjaf/j43wyyvr.htm 下列关于JavaScript的Date对象的getMonth()方法的返回值描述,正确的是(). A. 返回系统时间的当前月B. 返回值的范围介于1~12之间C. 返回系统时间的当

深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点(转)

才华横溢的Stoyan Stefanov,在他写的由O’Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会是件很美妙的事情.具体一点就是编写高质量JavaScript的一些要素,例如避免全局变量,使用单变量声明,在循环中预缓存length(长度),遵循代码阅读,以及更多. 此摘要也包括一些与代码不太相关的习惯,但对整体代码的创建息息相关,包括撰写API文档.执行同行评审以及运行JSLint.这些习惯和最佳做法可以

高级Javascript代码

Javascript是一门很吊的语言,我可能学了假的JavaScript,哈哈,大家还有什么推荐的,补充送那啥邀请码. 本文秉承着:你看不懂是你SB,我写的代码就要牛逼. 1.单行写一个评级组件 "★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate);定义一个变量rate是1到5的值,然后执行上面代码,看图 才发现插件什么的都弱爆了 来源:来自知乎用户蜗牛老湿的回答 2.如何装逼用代码骂别人SB (!(~+[])+{})[--[~+""][+

[转] 翻译-高质量JavaScript代码书写基本要点 ---张鑫旭

by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1173 原文作者:Stoyan Stefanov原文链接:The Essentials of Writing High Quality JavaScript翻译编辑:张鑫旭 //zxx: 俗不可耐的开场白就免了,直接进入翻译内容(其实是因为本文是在太..太..长了,). 教程相关细节主题:JavaScript最佳实践难度

引爆你的Javascript代码进化

方才在程序里看到一段JS代码,写法极为高明,私心想着若是其按照规范来写,定可培养对这门语言的理解,对JS编程能力提高必是极好的.说人话:丫代码写的太乱,看的窝火! 最近闲暇无事,准备对自己JS学习做一个总结.众所周知,JS是一种语法极其灵活的语言,一千个人会有一千种JS书写方式.这造成的结果往往就是给项目日后的开发及维护留下一个不小的隐患,也对你和团队再次开发及阅读代码造成一定困难,个人认为良好的书写规范是应该首当其冲的.所以参考一些优秀前端开发团队的代码规范后,总结了几点,希望能让你的Java

引爆你的Javascript代码进化 (转)

转自 海玉的博客 方才在程序里看到一段JS代码,写法极为高明,私心想着若是其按照规范来写,定可培养对这门语言的理解,对JS编程能力提高必是极好的.说人话:丫代码写的太乱,看的窝火! 最近闲暇无事,准备对自己JS学习做一个总结.众所周知,JS是一种语法极其灵活的语言,一千个人会有一千种JS书写方式.这造成的结果往往就是给项目日后的开发及维护留下一个不小的隐患,也对你和团队再次开发及阅读代码造成一定困难,个人认为良好的书写规范是应该首当其冲的.所以参考一些优秀前端开发团队的代码规范后,总结了几点,希