You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
assert.throws() does not accept an arrow function as the second argument #3275
Checkpoint 1
Checkpoint 2
Checkpoint 3
assert.js:271
} else if (actual instanceof expected) {
^
TypeError: Function has non-object prototype 'undefined' in instanceof check
at expectedException (assert.js:271:32)
at Function._throws (assert.js:310:8)
at Function.assert.throws (assert.js:319:11)
at Object.<anonymous> (/path/to/bug.js:10:8)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:118:18)
The results are the same no matter which of the following syntax is used:
Important thing to understand here is, arrow functions will not have their prototype property defined. It will be undefined. Since instanceof checks the prototypes and it couldn't find one in case of arrow functions, it throws that error.
Please keep in mind that, assert is not a general purpose assertion library.
My reading of the ES6 spec is that, for better or worse, V8's behavior is conforming. SpiderMonkey works the same way, FWIW. I'll file a pull request with a workaround.
It may be a silly idea, but I am afraid that f.prototype in your code snippet does not make sense to me.
You wrote:
Important thing to understand here is, arrow functions will not have their prototype property defined. It will be undefined. Since instanceof checks the prototypes and it couldn't find one in case of arrow functions, it throws that error.
I think the .prototype property belongs to the functions (constructors), while the .__proto__ (or the internal [[prototype]] property, to be exact) property belongs to the instances. To find the prototype of an instance, we use xxx.__proto__ or Object.getPrototypeOf(xxx). It should be equal to the .prototype property of the function used to construct the instance. The instanceof operator traces the prototype chain via the .__proto__ property, not the .prototype property.
I wonder why xxx instanceof Function or xxx.__proto__ === Function.prototype or Object.getPrototypeOf(xxx) === Function.prototype could not be used in assert.js. I just view the assert.js source code and I know why now: the code involved is dealing with the function's "first use case".
Is this issue broken again in Node 8.4.0 (or intentionally changed)? I'm experiencing the exact same issue here when trying to pass an arrow function as the second argument to .throws().
Activity
asukakenji commentedon Oct 8, 2015
May be related to: #3188
thefourtheye commentedon Oct 8, 2015
Important thing to understand here is, arrow functions will not have their
prototypeproperty defined. It will beundefined. Sinceinstanceofchecks the prototypes and it couldn't find one in case of arrow functions, it throws that error.Please keep in mind that,
assertis not a general purpose assertion library.bnoordhuis commentedon Oct 8, 2015
It is a somewhat unsatisfying dichotomy though, especially since
(function() {}).__proto__ === (() => {}).__proto__.thefourtheye commentedon Oct 8, 2015
True. I am not sure why they chose to compare
prototypeinstead of the internal property.Even this throws the same error.
bnoordhuis commentedon Oct 8, 2015
My reading of the ES6 spec is that, for better or worse, V8's behavior is conforming. SpiderMonkey works the same way, FWIW. I'll file a pull request with a workaround.
bnoordhuis commentedon Oct 8, 2015
#3276
asukakenji commentedon Oct 8, 2015
@thefourtheye :
It may be a silly idea, but I am afraid that
f.prototypein your code snippet does not make sense to me.You wrote:
I think the
.prototypeproperty belongs to the functions (constructors), while the.__proto__(or the internal[[prototype]]property, to be exact) property belongs to the instances. To find the prototype of an instance, we usexxx.__proto__orObject.getPrototypeOf(xxx). It should be equal to the.prototypeproperty of the function used to construct the instance. Theinstanceofoperator traces the prototype chain via the.__proto__property, not the.prototypeproperty.Here is a demonstration showing how it works:
I wonder whyI just view thexxx instanceof Functionorxxx.__proto__ === Function.prototypeorObject.getPrototypeOf(xxx) === Function.prototypecould not be used inassert.js.assert.jssource code and I know why now: the code involved is dealing with the function's "first use case".Here is a demonstration showing how they work:
I am using Node.js v4.1.2. I confirmed that using
use strictor--harmonyor both does not make a difference in the above results.asukakenji commentedon Oct 8, 2015
Some more ideas:
VS
assert: support arrow functions in .throws()
assert: support arrow functions in .throws()
lumaxis commentedon Aug 25, 2017
Is this issue broken again in Node 8.4.0 (or intentionally changed)? I'm experiencing the exact same issue here when trying to pass an arrow function as the second argument to
.throws().BridgeAR commentedon Aug 25, 2017
@lumaxis I can not reproduce this. Do you have a test case for me?
@asukakenji I updated your original examples to include the missing return statement in arrow functions with braces.