天天看點

關于面試題 Array.indexof() 方法的實作及思考

這是我在面試大公司時碰到的一個筆試題,當時自己雲裡霧裡的胡寫了一番,回頭也曾思考過,最終沒實作也就不了了之了。

昨天看到有網友說面試中也碰到過這個問題,我就重新思考了這個問題的實作方法。

對于想進大公司的童鞋,我想多說兩句,基礎知識真的很關鍵。平時在工作中也深刻體會到,沒有紮實的基礎知識,簡單問題容易複雜化。

因為存在

indexOf

的方法,是以自定義方法寫成

indexof

,友善對比。

對于

Array.indexof()

方法的實作,主要考察的就是原型繼承的知識。

通過

Array.prototype.indexof = function(){}

就可以給

Array

添加一個方法,實際工作中不推薦這樣做。

剩下的就是數組元素比對的問題,就不多說了,雖然不難,但是做的過程中也遇到了不大不小的問題。

最終代碼如下

關于面試題 Array.indexof() 方法的實作及思考
關于面試題 Array.indexof() 方法的實作及思考

Array.prototype.indexof = function(searchElement, fromIndex) {             var len = this.length;             // 首先判斷 fromIndex 是否合法             if (fromIndex == null) {                 fromIndex = 0;             }             if (fromIndex < 0) {                 fromIndex = len - 1;             }             // 循環判斷 searchElement 是否與數組内元素相等             for (var i = fromIndex; i < len; i++) {                 // 如果相等則傳回目前索引值                 if (searchElement === this[i]) {                     return i;                 }             }             return -1     }      

View Code

測試數組

var arr = ['a', '0', 0, 'a'];      

試了試,基本和原生方法差不多,沒有太明顯的bug,但是總覺得自己的代碼有些不夠簡練,邏輯不夠嚴謹。如果文章到此就結束了,顯的有點水。

翻 MDN 的時候看到了一個關于 Array.indexOf() 方法的 polyfill,因為該方法是 ECMAScript 第五版中實作的,是以沒有原生支援的時候就會用如下方法實作。也就是這個問題有了一個官方答案。我認為大家可以先不看官方代碼,自己嘗試着寫一寫,然後再對比答案就會發現自己的不足。

關于面試題 Array.indexof() 方法的實作及思考
關于面試題 Array.indexof() 方法的實作及思考
// Production steps of ECMA-262, Edition 5, 15.4.4.14     // Reference: http://es5.github.io/#x15.4.4.14     if (!Array.prototype.indexOf) {       Array.prototype.indexOf = function(searchElement, fromIndex) {         var k;         // 1. Let o be the result of calling ToObject passing         //    the this value as the argument.         if (this == null) {           throw new TypeError('"this" is null or not defined');         }         var o = Object(this);         // 2. Let lenValue be the result of calling the Get         //    internal method of o with the argument "length".         // 3. Let len be ToUint32(lenValue).         var len = o.length >>> 0;         // 4. If len is 0, return -1.         if (len === 0) {           return -1;         }         // 5. If argument fromIndex was passed let n be         //    ToInteger(fromIndex); else let n be 0.         var n = +fromIndex || 0;         if (Math.abs(n) === Infinity) {           n = 0;         }         // 6. If n >= len, return -1.         if (n >= len) {           return -1;         }         // 7. If n >= 0, then Let k be n.         // 8. Else, n<0, Let k be len - abs(n).         //    If k is less than 0, then let k be 0.         k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);         // 9. Repeat, while k < len         while (k < len) {           // a. Let Pk be ToString(k).           //   This is implicit for LHS operands of the in operator           // b. Let kPresent be the result of calling the           //    HasProperty internal method of o with argument Pk.           //   This step can be combined with c           // c. If kPresent is true, then           //    i.  Let elementK be the result of calling the Get           //        internal method of o with the argument ToString(k).           //   ii.  Let same be the result of applying the           //        Strict Equality Comparison Algorithm to           //        searchElement and elementK.           //  iii.  If same is true, return k.           if (k in o && o[k] === searchElement) {             return k;           }           k++;         }         return -1;       };     }      

仔細看了看官方代碼,思路清晰,邏輯嚴謹,代碼簡潔,再回頭看看自己的代碼,真是慘不忍睹,實在很慚愧。這個問題不難,但是通過閱讀官方代碼,發現這其中有很多值得學習的地方,尤其是條件判斷是否全面,考慮問題是否周到。我從不敢以程式員自诩,至少現在看來自己還不夠格。解決一個問題很簡單,但是能不能把問題解決好就是能力的展現。

感謝您的閱讀,如果您對我的文章感興趣,可以關注我的部落格,我是叙帝利,下篇文章再見!

開發低代碼平台的必備拖拽庫 https://github.com/ng-dnd/ng-dnd

基于 Angular Material 的中背景管理架構 https://github.com/ng-matero/ng-matero

Angular Material Extensions 擴充元件庫 https://github.com/ng-matero/extensions

仿 Windows 照片檢視器插件 https://github.com/nzbin/photoviewer

仿 Windows 照片檢視器插件 jQuery 版 https://github.com/nzbin/magnify

完美替代 jQuery 的子產品化 DOM 庫 https://github.com/nzbin/domq

簡化類名的輕量級 CSS 架構 https://github.com/nzbin/snack

與任意 UI 架構搭配使用的通用輔助類 https://github.com/nzbin/snack-helper

單元素純 CSS 加載動畫 https://github.com/nzbin/three-dots

有趣的 jQuery 卡片抽獎插件 https://github.com/nzbin/CardShow

懸疑科幻電影推薦 https://github.com/nzbin/movie-gallery

鍛煉記憶力的小程式 https://github.com/nzbin/memory-stake

繼續閱讀