When a JavaScript function is not a function

Hero Image

One would think that a function is a function is a function. Right? Wrong.

Consider this node.js code:

   var f = function () {}  
console.log('f instanceof Function in the main context: ' + (f instanceof Function))  
  
require('vm').runInNewContext(  
    "console.log('f instanceof Function in child context: ' + (f instanceof Function))",  
    { console: console, f: f })  

  

Turns out that a function in the main V8 context is not a function in the child V8 context, at least according to JavaScript's instanceof:


f instanceof Function in the main context: true  
f instanceof Function in child context: false
  

The reason for this can be easily explained after reading (and probably re-reading a few times) the great write-up on prototypical inheritance. The f function is created in the main context and has main context's Function object in its prototype chain. When instanceof is run in the child context against the f function created in the main context, it fails to find the child context's Function object in f's prototype chain. Knowing that, the problem can be fixed by sharing main context's Function object with the child context using the global object:

var f = function () {}  
console.log('f instanceof Function in the main context: ' + (f instanceof Function))  
  
require('vm').runInNewContext(  
    "console.log('f instanceof Function in child context: ' + (f instanceof Function))",  
    { console: console, f: f, Function: Function })  

  

Which leads to the expected:


f instanceof Function in the main context: true  
f instanceof Function in child context: true
  

However, sharing objects between V8 contexts probably defeats the purpose of using separate V8 contexts in the first place, at least for some applications. After all, V8 contexts are meant to isolate in memory state. So a safe alternative that does not require sharing the Function object is using

typeof f === 'function'
  

check instead of the original

f instanceof Function
  

End of trivia.


ArrowPrevious
NextArrow

Most Recent

24 January 2022
Run Node.js from Google Sheets

Import data from any API or data source to Google Sheets using Node.js, NPM, and Fusebit Connectors.

21 January 2022
Linear and Discord Slash Commands

Learn how to build an interactive Slash Command for a Discord bot that lets users create a new issue in Linear.

19 January 2022
Add Slash Commands to Your Discord Bot!

Slash Commands are an extremely powerful way to provide rich interactivity for members of your Discord server, all you have to do is type “/” and you're ready to use your favorite bot.