你的位置:首页 > Java教程

[Java教程]关于面试题 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++) {      // 如果相等则返回当前索引值      else 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.14if (!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

仔细看了看官方代码,思路清晰,逻辑严谨,代码简洁,再回头看看自己的代码,真的不忍直视,实在很惭愧。这个问题不难,但是通过阅读官方代码,发现这其中有很多值得学习的地方,尤其是条件判断是否全面,考虑问题是否周到。我从不敢以程序员自诩,至少现在看来自己还不够格。解决一个问题很简单,但是能不能把问题解决好就是能力的体现。