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)));
}
điều này phải đủ tốt. chức năng này thực hiện các thử nghiệm sau:
- null hoặc undefined;
- thông số thực sự là một hàm;
- các param là Function.prototype bản thân (đây là một trường hợp đặc biệt, nơi mang lại cho Function.prototype.toString
function Empty(){}
)
- các cơ quan chức năng là chính xác
function <valid_function_name> (<valid_param_list>) { [native code] }
regex là một chút phức tạp, nhưng nó thực sự chạy khá nhanh chóng trong chrome trên máy tính xách tay lenovo 4GB của tôi (bộ đôi lõi):
var n = (new Date).getTime();
for (var i = 0; i < 1000000; i++) {
i%2 ? isFuncNative(isFuncNative) :
isFuncNative(document.getElementById);
};
(new Date).getTime() - n;
3023ms. do đó, chức năng mất khoảng 3 micro-sec để chạy một khi tất cả là JIT'ed.
Nó hoạt động trong tất cả các trình duyệt. Trước đây, tôi đã sử dụng Function.prototype.toString.call, điều này làm hỏng IE, vì trong IE, các phương thức phần tử DOM và các phương thức cửa sổ là các hàm NOT, nhưng các đối tượng và chúng không có phương thức toString. String constructor giải quyết vấn đề một cách tao nhã.
Điều này sẽ chỉ làm việc nếu toString đã không được ghi đè, không có? – joekarl
@jAndy Điều này có thực sự không? Tôi nghĩ 'toString' không hoạt động trong tất cả các trình duyệt hiện đại hay gì đó. – William
@joekit nếu 'toString' bị ghi đè, bạn sẽ có thể thực hiện' Function.prototype.toString.call (obj) .indexOf ('[native code]'); 'Ngoài ra, có lẽ nên sử dụng RegExp tốt hơn. Hãy thử gọi chức năng chống lại chính nó, và nó sẽ đi qua như ** native ** bởi vì nó xuất hiện trong chuỗi. – William