2014-12-29 2 views
0

Есть ли общий способ определения собственных функций в Node.js?Общий способ определения собственных функций в узле js

Например, чтобы проверить на собственную функцию в браузере, я хотел бы использовать это - function isNative(fn) { return (/{\s*[native code]\s*}/).test('' + fn); }

Есть ли что-то подобное мы можем использовать для обнаружения нативных Node.js функций, таких как fs.readFile и так далее?

Я предполагаю, что один из способов - проверить кеширование функций, доступных в переменной GLOBAL, до начала программы, есть ли более элегантный способ?

Спасибо!

ответ

-1

Еще один возможный (и определенно «не элегантный») подход к решению: проверить все стандартные пакеты Node.js с их именами функций (я подготовил список стандартных модулей для v0.10.35 из папки Node.js github /lib согласно N recomendations on Core Modules).

К сожалению, Node.js не сохраняет информацию о загруженных базовых модулях в require.cache, поэтому их невозможно обнаружить таким образом.

Функция testNative() обнаруживает почти все «нативные» функции, за исключением require() (и, возможно, некоторые другие функции, написанные на JavaScript и находящиеся за пределами модулей Node.js).

Комментарии:

  1. заполняют native_fns массив внутри функции testNative(). Если он медленный, вы можете извлечь эту часть вне функции.
  2. Функция использует eval() для обнаружения загруженных модулей, поэтому вам необходимо следовать правилу правильного именования.

Таким образом, функция тест работает только, если вы всегда использовать стандартные имена переменных для библиотеки переменных:

var fs = require('fs'); // good 
var myfs = require('fs'); // bad 

UPDATE: Эта уродливая часть может быть заменен анализом process.moduleList.

Код:

function testNative(fn) { 
    if(!!fn.toString().match(/{\s*\[native code\]\s*}/)) return true; 

    var std_modules = ['assert','buffer','child_process','cluster','console','constants', 
     'crypto','dgram','dns','domain','events','freelist','fs','http','https','module', 
     'net','os','path','punycode','querystring','readline','repl','smalloc','stream', 
     'string_decoder','sys','timers','tls','tracing','tty','url','util','vm','zlib', 
     'Math','JSON']; 

    var native_fns = []; 
    for(var i=0; i<std_modules.length;i++) { 
     try { 
      var module = eval(std_modules[i]); 
      native_fns.push(module); 
      if(module) { 
       for(var k in module) { 
        native_fns.push(module[k]); 
       } 
      } 
     } catch (err) {} 
    } 

    return native_fns.indexOf(fn) > -1; 
} 

// Test 
function foo() {return 1}; 
var fs = require('fs'); 

console.log(testNative(fs.readFile)); // true 
console.log(testNative(foo));   // false 
console.log(testNative(JSON.stringify)); // true 
+0

Используя стандартные имена модулей всегда является слишком сильным предположением, чтобы я думаю – everconfusedGuy

0

Проблема заключается в том BUILTIN функция этого узла является технически неродной (для v8). Единственный способ это проверить имя функция происхождения файла:

var FunctionOrigin = require('function-origin'); 
var natives = process.binding('natives'); 

function isNative(fn) { 
    var file = FunctionOrigin(fn).file; 
    var noExt = file.slice(0, file.length - 3); 

    return natives.hasOwnProperty(noExt); 
} 


function Test(){} 


console.log(isNative(require('fs').readFile)); 
console.log(isNative(Test)); 
+0

Он отлично работает, за исключением «родные» функций в JavaScript, например, JSON.stringify() или setInterval(). К сожалению, я не могу установить модуль «function-origin» в Windows, только на Mac, но думаю, что это проблема установки Node.js. – agershun

+0

для 'JSON.stringify' вы можете проверить' toString', он действительно является родным. для 'setInterval' это должно работать – vkurchatkin

+0

Извините, для setInterval, setTimeout - это не так. Для require - это нормально. – agershun