這是我在面試大公司時碰到的一個筆試題,當時自己雲里霧裡的胡寫了一番,回頭也曾思考過,最終沒實現也就不了了之了。 昨天看到有網友說面試中也碰到過這個問題,我就重新思考了這個問題的實現方法。 對於想進大公司的童鞋,我想多說兩句,基礎知識真的很關鍵。平時在工作中也深刻體會到,沒有扎實的基礎知識,簡單問題容 ...
這是我在面試大公司時碰到的一個筆試題,當時自己雲里霧裡的胡寫了一番,回頭也曾思考過,最終沒實現也就不了了之了。
昨天看到有網友說面試中也碰到過這個問題,我就重新思考了這個問題的實現方法。
對於想進大公司的童鞋,我想多說兩句,基礎知識真的很關鍵。平時在工作中也深刻體會到,沒有扎實的基礎知識,簡單問題容易複雜化。
因為存在 indexOf 的方法,所以自定義方法寫成 indexof ,方便對比。
對於 Array.indexof() 方法的實現,主要考察的就是原型繼承的知識。
通過 Array.prototype.indexof = function(){} 就可以給 Array 添加一個方法,實際工作中不推薦這樣做。
剩下的就是數組元素匹配的問題,就不多說了,雖然不難,但是做的過程中也遇到了不大不小的問題。
最終代碼如下
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 第五版中實現的,所以沒有原生支持的時候就會用如下方法實現。也就是這個問題有了一個官方答案。我認為大家可以先不看官方代碼,自己嘗試著寫一寫,然後再對比答案就會發現自己的不足。
// 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; }; }View Code
仔細看了看官方代碼,思路清晰,邏輯嚴謹,代碼簡潔,再回頭看看自己的代碼,真的不忍直視,實在很慚愧。這個問題不難,但是通過閱讀官方代碼,發現這其中有很多值得學習的地方,尤其是條件判斷是否全面,考慮問題是否周到。我從不敢以程式員自詡,至少現在看來自己還不夠格。解決一個問題很簡單,但是能不能把問題解決好就是能力的體現。