Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect if function is native to browser

I am trying to iterate over all the globals defined in a website, but in doing so I am also getting the native browser functions.

var numf=0; var nump=0; var numo=0;  for(var p in this) {      if(typeof(this[p]) === "function"){         numf+=1;         console.log(p+"()");     } else if(typeof p != 'undefined'){         nump+=1;         console.log(p);     } else {          numo+=1;         console.log(p);     } } 

Is there a way to determine if a function is native to the browser or created in a script?

like image 288
asawilliams Avatar asked Jul 06 '11 15:07

asawilliams


People also ask

How do you find whether a function exists or not?

One way to check if a function is defined is to test it with an if statement. The trick is to test the function as a method of the window object. The code in the brackets will execute if the function is defined.

How do I check my browser focus?

Use the visibilitychange event to detect if a browser tab has focus or not, e.g. document. addEventListener('visibilitychange', checkTabFocused) . The event is fired at the document when the contents of its tab have become visible or have been hidden.

Is there a way to detect if a browser window is not currently active?

You can use the focus and blur events on the window object to check if the window is still active like so: window. addEventListener('focus', function (event) { console.

What is JavaScript native code?

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.


2 Answers

You can call the inherited .toString() function on the methods and check the outcome. Native methods will have a block like [native code].

if( this[p].toString().indexOf('[native code]') > -1 ) {     // yep, native in the browser } 

Update because a lot of commentators want some clarification and people really have a requirement for such a detection. To make this check really save, we should probably use a line line this:

if( /\{\s+\[native code\]/.test( Function.prototype.toString.call( this[ p ] ) ) ) {     // yep, native } 

Now we're using the .toString method from the prototype of Function which makes it very unlikely if not impossible some other script has overwritten the toString method. Secondly we're checking with a regular expression so we can't get fooled by comments within the function body.

like image 127
jAndy Avatar answered Sep 22 '22 07:09

jAndy


function isFuncNative(f) {        return !!f && (typeof f).toLowerCase() == 'function'         && (f === Function.prototype         || /^\s*function\s*(\b[a-z$_][a-z0-9$_]*\b)*\s*\((|([a-z$_][a-z0-9$_]*)(\s*,[a-z$_][a-z0-9$_]*)*)\)\s*{\s*\[native code\]\s*}\s*$/i.test(String(f))); } 

this should be good enough. this function does the following tests:

  1. null or undefined;
  2. the param is actually a function;
  3. the param is Function.prototype itself (this is a special case, where Function.prototype.toString gives function Empty(){})
  4. the function body is exactly function <valid_function_name> (<valid_param_list>) { [native code] }

the regex is a little bit complicated, but it actually runs pretty decently fast in chrome on my 4GB lenovo laptop (duo core):

var n = (new Date).getTime();  for (var i = 0; i < 1000000; i++) {     i%2 ? isFuncNative(isFuncNative) :            isFuncNative(document.getElementById); };  (new Date).getTime() - n; 

3023ms. so the function takes somewhere around 3 micro-sec to run once all is JIT'ed.

It works in all browsers. Previously, I used Function.prototype.toString.call, this crashes IE, since in IE, the DOM element methods and window methods are NOT functions, but objects, and they don't have toString method. String constructor solves the problem elegantly.

like image 25
Yong Avatar answered Sep 18 '22 07:09

Yong