Čas od času otestuji, zda je daná funkce nativním kódem – je to důležitá součást testování funkcí, zda byla funkce poskytnuta prohlížečem nebo prostřednictvím shim třetí strany, který se chová jako nativní funkce. Nejlepší způsob, jak to zjistit, je samozřejmě vyhodnocení toString
návratová hodnota funkce.
JavaScript
Kód k provedení tohoto úkolu je poměrně jednoduchý:
function isNative(fn) { return (/\{\s*\[native code\]\s*\}/).test('' + fn); }
Provádí se převod na řetězcovou reprezentaci funkce a provedení shody regulárního výrazu v řetězci. Neexistuje lepší způsob, jak potvrdit, že funkce je nativní kód!
Aktualizovat!
Tvůrce Lodash John-David Dalton poskytl lepší řešení:
;(function() { // Used to resolve the internal `[[Class]]` of values var toString = Object.prototype.toString; // Used to resolve the decompiled source of functions var fnToString = Function.prototype.toString; // Used to detect host constructors (Safari > 4; really typed array specific) var reHostCtor = /^\[object .+?Constructor\]$/; // Compile a regexp using a common native method as a template. // We chose `Object#toString` because there's a good chance it is not being mucked with. var reNative = RegExp('^' + // Coerce `Object#toString` to a string String(toString) // Escape any special regexp characters .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&') // Replace mentions of `toString` with `.*?` to keep the template generic. // Replace thing like `for ...` to support environments like Rhino which add extra info // such as method arity. .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); function isNative(value) { var type = typeof value; return type == 'function' // Use `Function#toString` to bypass the value's own `toString` method // and avoid being faked out. ? reNative.test(fnToString.call(value)) // Fallback to a host object check because some environments will represent // things like typed arrays as DOM methods which may not conform to the // normal native pattern. : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false; } // export however you want module.exports = isNative; }());
Takže tady to máte – lepší řešení pro zjištění, zda je metoda nativní. Samozřejmě byste to neměli používat jako formu zabezpečení – jde pouze o naznačení nativní podpory!