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


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

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

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

因為存在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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM