Clearscript: Is there any way to add a script function to a host type?

Created on 24 Jun 2019  路  2Comments  路  Source: microsoft/ClearScript

Is it possible to add a script function to a host type? The below code throws an exception when I try to add function _greet_ to type _Person_. A host type apparently has no prototype?

using Microsoft.ClearScript.V8;
using System;

namespace ClearScriptDemo
{
    class Person
    {
        public string GetName()
        {
            return "John Doe";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var engine = new V8ScriptEngine())
            {
                // expose a host type
                engine.AddHostType("Console", typeof(Console));
                engine.Execute("Console.WriteLine('{0} is an interesting number.', Math.PI)");

                // expose a host object
                engine.AccessContext = typeof(Program);
                engine.AddHostObject("person", new Person());
                engine.Execute("Console.WriteLine(person.GetName())");

                // add script function to host type
                engine.Execute("person.prototype.greet = function() { Console.WriteLine(\"Hello, World!\"); }");

                Console.ReadKey();
            }
        }
    }
}

Exception:
An unhandled exception of type 'Microsoft.ClearScript.ScriptEngineException' occurred in ClearScriptV8-64.dll

Additional information: TypeError: Cannot set property 'greet' of undefined

question

All 2 comments

Hi @tu-lehong,

Neither host objects nor host types have a prototype property (unless the corresponding .NET object or type exposes such a property). However, there are many ways to extend such objects in JavaScript.

One way is to add a link to the object's prototype chain:

function extendHostObject(hostObject) {
    let proto = {};
    proto._proto = proto;
    Object.setPrototypeOf(proto, Object.getPrototypeOf(hostObject));
    Object.setPrototypeOf(hostObject, proto);
}
extendHostObject(person);
person._proto.greet = function() {
    Console.WriteLine('Hello, World!');
}
person.greet();

A more flexible solution is to wrap the object in a Proxy. That way you can add extensions and even override existing host properties.

Good luck!

Thank you!

Was this page helpful?
0 / 5 - 0 ratings