Njs: the prototype property of a Function instance is non-writable

Created on 26 Jul 2018  路  6Comments  路  Source: nginx/njs

JSON.stringify(Object.getOwnPropertyDescriptor(function() {}, 'prototype'))
{"value":{},"configurable":false,"enumerable":false,"writable":false}

So, one is unable to do inheritance, instanceof checks, etc...

ES5.1 feature

All 6 comments

@drsm

Take a look: https://gist.github.com/4d6de7a04d459a7ba46bc6012dd64417
The early alpha patch.

 === Summary ===
  - Ran 27119 tests
- - Passed 8308 tests (30.6%)
- - Failed 18811 tests (69.4%)
+ - Passed 8467 tests (31.2%)
+ - Failed 18652 tests (68.8%)

You can ignore "InternalError: assigning non-object value as prototype" I will fix it later (only 5 tests in test262).

You can provide more test cases to cover.

@xeioex

  • the property became non-writable after the first reassignment.
>> var f = function() {}, a = {t: 1}, b = {t: 2};
undefined
>> f.prototype = a
{
 t: 1
}
>> f.prototype = b
TypeError: Cannot assign to read-only property "prototype" of function
    at main (native)
  • the same after function call:
>> var y = function() {}
undefined
>> Object.getOwnPropertyDescriptor(y, 'prototype').writable
true
>> var x = new y()
undefined
>> Object.getOwnPropertyDescriptor(y, 'prototype').writable
false
>> var y = function() {}
undefined
>> Object.getOwnPropertyDescriptor(y, 'prototype').writable
true
>> y()
undefined
>> Object.getOwnPropertyDescriptor(y, 'prototype').writable
false

both cases above are weird, but should work.

  • base functionality - ok
>> var x = {}, y = function() {}, z; y.prototype = x; z = new y()
{}
>> (z instanceof y) && (z.__proto__ == y.prototype) && (x.isPrototypeOf(z))
true

You can ignore "InternalError: assigning non-object value as prototype" I will fix it later (only 5 tests in test262).

https://tc39.es/ecma262/#sec-getprototypefromconstructor

the test:

[undefined, null, false, NaN, '']
.map((x) => { var f = function() {}; f.prototype = x; return Object.getPrototypeOf(new f()); })
.every((x) => x == Object.prototype)
// true

[undefined, null, false, NaN, '']
.map((x) => { var f = function() {}; f.prototype = x; return f; })
.map((x) => { try { return ({} instanceof x) ? 1 : 2; } catch (e) { return (e instanceof TypeError) ? 3 : 4; } })
.every((x) => x == 3);
// true

@drsm

Take a look: https://gist.github.com/b055f97900ceef6bcac7b4073583f332
All provided tests passed.

@xeioex

Looks good to me! Thanks!

The intent was:

+    { njs_str("var F = function() {}, a = {t: 1}, b = {t: 2}, x, y;"
+              "F.prototype = a; x = new F();"
+              "F.prototype = b; y = new F();"
+              "x.t == 1 && y.t == 2"),
+      njs_str("true") },
Was this page helpful?
0 / 5 - 0 ratings

Related issues

an0ma1ia picture an0ma1ia  路  4Comments

drsm picture drsm  路  5Comments

drsm picture drsm  路  5Comments

porunov picture porunov  路  4Comments

xeioex picture xeioex  路  3Comments