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
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!