;(function() {
// Используется для разложения на составляющие внутреннего `[[Class]]` значений
var toString = Object.prototype.toString;
// Используется для разложения на составляющие декомпилированного
// исходного кода функции
var fnToString = Function.prototype.toString;
// Используется для определения конструкторов среды (Safari > 4;
// по сути, предназначено специально для типизированных массивов)
var reHostCtor = /^\[object .+?Constructor\]$/;
// Составление регулярного выражения на основе часто употребляемого
// нативного метода в качестве шаблона.
// Выбираем `Object#toString`, так как вполне вероятно, что он ещё не задействован.
var reNative = RegExp('^' +
// Применяем `Object#toString` к строке
String(toString)
// Избавляемся от любых специальных символов регулярных выражений
.replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&')
// Заменяем упоминания `toString` на `.*?`, чтобы сохранить обобщённый вид шаблона.
// Заменяем `for ...` и тому подобное для поддержки окружений вроде Rhino,
// которые добавляют дополнительную информацию, такую как арность метода.
.replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
);
function isNative(value) {
var type = typeof value;
return type == 'function'
// Используем `Function#toString`, чтобы обойти собственный метод
// `toString` самого значения и избежать ложного результата.
? reNative.test(fnToString.call(value))
// На всякий случай выполняем проверку на наличие объектов среды, так
// как некоторые окружения могут представлять компоненты вроде
// типизированных массивов как методы DOM, что может не соответствовать
// нормальному нативному паттерну.
: (value && type == 'object' && reHostCtor.test(toString.call(value))) || false;
}
// экспортируем в удобном для вас виде
module.exports = isNative;
}());
Комментариев нет:
Отправить комментарий