Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS Type System vs CLR Type System (inheritance behavior) #284

Open
mainlyer opened this issue Mar 24, 2023 · 3 comments
Open

JS Type System vs CLR Type System (inheritance behavior) #284

mainlyer opened this issue Mar 24, 2023 · 3 comments

Comments

@mainlyer
Copy link

Hi. I found a weird behavior of ineritance and I don't know if this is the expected behavior or not. The issue is relative to the instanceof operator. When the declaracion/creation is inside a script, all works as I expected:

class A { }
class B extends A { }

const a = new A();
const b = new B();

console.log('typeof a == typeof b:', typeof a == typeof b); // true
console.log('typeof a === typeof b:', typeof a === typeof b); // true
console.log('a instanceof A:', a instanceof A); // true
console.log('a instanceof B:', a instanceof B); // false
console.log('b instanceof B:', b instanceof B); // true
console.log('b instanceof A:', b instanceof A); // true
console.log('B.prototype instanceof A:', B.prototype instanceof A); // true

But when coming from CLR, the behavior is different. I derived the base class from JSObject, because if not, the result is still worst.

class A : JSObject
{
    public A()
    {
        this.ValueType = JSValueType.Object;
        this.Value = this;
    }
}

class B : A
{
}

And the result is:

var context = new NiL.JS.Core.Context();

context.DefineConstructor(typeof(A));
context.DefineConstructor(typeof(B));
context.DefineVariable("a").Assign(new A());
context.DefineVariable("b").Assign(new B());

var t1 = context.Eval("typeof a == typeof b").Value; // true
var t2 = context.Eval("typeof a === typeof b").Value; // true
var t3 = context.Eval("a instanceof A").Value; // true
var t4 = context.Eval("a instanceof B").Value; // false
var t5 = context.Eval("b instanceof B").Value; // true
var t6 = context.Eval("b instanceof A").Value; // false <-------------- why ?
var t7 = context.Eval("B.prototype instanceof A").Value; // false <---- why ?

Is there a way to change this behavior throw JSObject? Am I wrong? With DefineConstant, obviously, nothing change.

Thank you in advance.

@nilproject
Copy link
Owner

Yes, it's expected behaviour. Inheritance in JS is not like inheritance in C#. When some type is proxied to JS environment, wrapper for it is created, which is JS object. Class A and B are different classes, so, engine creates different wrappers for them. You can mark class B with PrototypeAttribute(typeof(A)). After that instanceof will work as you expect

@mainlyer
Copy link
Author

Thank you a lot. One part of the javascript implementation highly depends on references and types. Another question, when calling a CLR method, is posible to get it working in Camel case in javascript? Is there a way to avoid duplication of method names? Its only for naming conventions.

Thank a lot again.

@nilproject
Copy link
Owner

There is JavaScriptNameAttribute exactly for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants