Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine that a JavaScript function is native (without testing '[native code]')

I would like to know if there is a way to differentiate a JavaScript script function (function(){}) from a JavaScript native function (like Math.cos).
I already know the func.toString().indexOf('[native code]') != -1 trick but I was wondering if there is another way to detect it.

context:
I need to create a No-op forwarding ES6 Proxy that can handle native functions on an object but it fails with TypeError: Illegal invocation (see Illegal invocation error using ES6 Proxy and node.js).

To workaround this I .bind() all my functions in the get handler of my Proxy but if I could detect native function effectively, I will only need to .bind() these native functions.

more details: https://github.com/FranckFreiburger/module-invalidate/blob/master/index.js#L106

note:

(function() {}).toString() -> "function () {}"
(function() {}).prototype  -> {}

(require('os').cpus).toString() -> "function getCPUs() { [native code] }"
(require('os').cpus).prototype  -> getCPUs {}

(Math.cos).toString() -> "function cos() { [native code] }"
(Math.cos).prototype  -> undefined

(Promise.resolve().then).toString() -> "function then() { [native code] }"
(Promise.resolve().then).prototype  -> undefined

edit:
For the moment, the best solution is to test !('prototype' in fun) but it will not work with require('os').cpus ...

like image 603
Franck Freiburger Avatar asked Mar 04 '17 10:03

Franck Freiburger


People also ask

What is a native code in JavaScript?

Native code is computer programming (code) that is compiled to run with a particular processor (such as an Intel x86-class processor) and its set of instructions. If the same program is run on a computer with a different processor, software can be provided so that the computer emulates the original processor.

What is native code in Chrome?

Native Client is a set of open source tools that allow Chrome to run compiled C and C++ code the same way the browser currently runs JavaScript or other common web programming languages. Native Code offers both a security sandbox and a set of interfaces that provide C and C++ bindings to the capabilities of HTML5.


1 Answers

You could try to use a Function constructor with the toString value of the function. If it does not throw an error, then you get a custom function, otherwise you have a native function.

function isNativeFn(fn) {
    try {
        void new Function(fn.toString());    
    } catch (e) {
        return true;
    }
    return false;
}

function customFn() { var foo; }

console.log(isNativeFn(Math.cos));          // true
console.log(isNativeFn(customFn));          // false
console.log(isNativeFn(customFn.bind({}))); // true, because bind 
like image 198
Nina Scholz Avatar answered Sep 30 '22 16:09

Nina Scholz