Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
575 views
in Technique[技术] by (71.8m points)

node.js - 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 ...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...