js如何判斷一個方法是內建的還是自定義的

admin發表於2017-03-31

可能在實際應用中有這樣的需求,判斷一個方法是JavaScript內建的,還是自定義的。

當然這樣的需求並不多,下面就通過程式碼示例做一下介紹,先看一段程式碼示例:

[JavaScript] 純文字檢視 複製程式碼
console.log(alert.toString());

特別說明:本站編輯器無法正確執行上面的程式碼,在本機測試。

執行結果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201703/31/101929in2uhet1nnlk6n21.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

內建的方法會隱藏內部實現,會顯示上圖所示的內容,所以利用這個特點就可以實現簡單的判斷功能。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
function isNative(fn) { 
  return (/\{\s*\[native code\]\s*\}/).test('' + fn); 
}
console.log(isNative(alert));

特別說明:上面的程式碼依然無法再本編輯器中正常測試,需要在本機進行測試。

''+fn的作用是將函式隱式轉換為字串,和fn.toString()效果一樣。

上面的程式碼比較簡單,還有一位大神寫的比較完美的程式碼,也可以實現此功能,感興趣的朋友可以自行做一下分析。

程式碼如下:

[JavaScript] 純文字檢視 複製程式碼
;(function() { 
  // 取得Object的toString方法,用於處理傳入引數value的內部(internal) `[[Class]]` 
  var toString = Object.prototype.toString; 
  
  // 取得原始的Function的toString方法,用於處理functions的反編譯程式碼 
  var fnToString = Function.prototype.toString; 
  
  // 用於檢測 宿主物件構造器(host constructors), 
  // (Safari > 4; 真的輸出特定的陣列,really typed array specific) 
  var reHostCtor = /^\[object .+?Constructor\]$/; 
  
  // 使用RegExp將常用的native方法編譯為正則模板. 
  // 使用 `Object#toString` 是因為一般他不會被汙染 
  var reNative = RegExp('^' + 
  // 將 `Object#toString` 強轉為字串 
  String(toString) 
  // 對所有正規表示式相關的特殊字元進行轉義 
  .replace(/[.*+?^${}()|[\]\/\\]/g, '\\$&') 
  // 為了保持模板的通用性,將 `toString` 替換為 `.*?` 
  // 將`for ...`之類的字元替換,相容Rhino等環境,因為他們會有額外的資訊,如方法的引數數量. 
  .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') 
  // 結束符 
  + '$'); 
  
  function isNative(value) { 
    // 判斷 typeof 
    var type = typeof value; 
    return type == 'function'
    // 使用 `Function#toString`原生方法來呼叫, 
    // 而不是 value 自己的 `toString` 方法, 
    // 以免被偽造所欺騙. 
    ? reNative.test(fnToString.call(value)) 
    // 如果type 不是'function', 
    // 則需要檢查宿主物件(host object)的情形, 
    // 因為某些(瀏覽器)環境會將 typed arrays 之類的東西當作DOM方法 
    // 此時可能不匹配標準的Native正則模式 
    : (value && type == 'object' && reHostCtor.test(toString.call(value))) || false; 
  }; 
  // 可以將 isNative 賦值給你想要的變數/物件 
  window.isNative = isNative; 
}());

相關文章