asa*_*ams 23 javascript global-variables
我试图迭代网站中定义的所有全局变量,但这样做我也得到了本机浏览器功能.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法确定某个函数是浏览器的本机函数还是脚本中创建的函数?
jAn*_*ndy 14
您可以.toString()在方法上调用继承的函数并检查结果.本机方法会有一个块[native code].
if( this[p].toString().indexOf('[native code]') > -1 ) {
// yep, native in the browser
}
Run Code Online (Sandbox Code Playgroud)
更新是因为很多评论员都希望得到一些澄清,人们确实需要这样的检测.为了使这个检查确实保存,我们应该使用这一行:
if( /\{\s+\[native code\]/.test( Function.prototype.toString.call( this[ p ] ) ) ) {
// yep, native
}
Run Code Online (Sandbox Code Playgroud)
现在,我们正在使用的.toString方法从prototype的Function,这使得它不太可能,如果不是不可能一些其他的脚本已覆盖的toString方法.其次,我们使用正则表达式进行检查,这样我们就不会被函数体内的注释所迷惑.
Yon*_*ong 10
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)));
}
Run Code Online (Sandbox Code Playgroud)
这应该足够好了.此函数执行以下测试:
function Empty(){})function <valid_function_name> (<valid_param_list>) { [native code] }正则表达式有点复杂,但它实际上在我的4GB lenovo笔记本电脑(双核心)上以相当快的速度运行:
var n = (new Date).getTime();
for (var i = 0; i < 1000000; i++) {
i%2 ? isFuncNative(isFuncNative) :
isFuncNative(document.getElementById);
};
(new Date).getTime() - n;
Run Code Online (Sandbox Code Playgroud)
3023ms.因此,一旦JIT全部运行,该功能需要大约3微秒才能运行.
它适用于所有浏览器.以前,我使用了Function.prototype.toString.call,这会导致IE崩溃,因为在IE中,DOM元素方法和窗口方法都不是函数,而是对象,而且它们没有toString方法.字符串构造函数优雅地解决了这个问题.