这是我在面试大公司时碰到的一个笔试题,当时自己云里雾里的胡写了一番,回头也曾思考过,最终没实现也就不了了之了。

昨天看到有网友说面试中也碰到过这个问题,我就重新思考了这个问题的实现方法。

对于想进大公司的童鞋,我想多说两句,基础知识真的很关键。平时在工作中也深刻体会到,没有扎实的基础知识,简单问题容易复杂化。

因为存在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
}

测试数组

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;
};
}

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

关于面试题 Array.indexof() 方法的实现及思考的更多相关文章

  1. 2016 - 2 - 19 ARC内存管理知识总结(一,arc基本概念及alloc等方法的实现)

    一. ARC的基本概念 1. 在objc中采用automatic reference counting 机制, 让编译器来进行内存管理.在降低程序崩溃,内存管理泄漏等风险的同时,很大程度减少了程序员的 ...

  2. OC:属性的内部实现原理、dealloc内释放实例变量、便利构造器方法的实现原理、collection的内存管理

    代码: // // main.m #import <Foundation/Foundation.h> #import "Person.h" #import " ...

  3. java集合的contains(obj)方法的实现

    在实际项目中我们通常会有一个需求就是:想知道在一个列表中是否包含某一个对象 这里ArrayList表.HashSet表和HashMap表都提供了一个contains(obj)方法, 下面说一下两个列表 ...

  4. JavaScript中子类调用父类方法的实现

    一.前言 最近在项目中,前端框架使用JavaScript面向对象编程,遇到了诸多问题,其中最典型的问题就是子类调用父类(super class)同名方法,也就是如C#中子类中调用父类函数base.** ...

  5. java学习-Comparable<Integer>接口方法的实现

    基本数据类型的包装类Integer, Float, Double,Long,Byte等都实现的Comparable接口,用于列表List或数组arrays的排序 Comparable<Integ ...

  6. new方法的实现原理

    // // main.m // 04-new方法的实现原理 #import <Foundation/Foundation.h> #import "Person.h" # ...

  7. JavaScript内置一些方法的实现原理--new关键字,call/apply/bind方法--实现

    先学习下new操作符吧 new关键字调用函数的心路历程: 1.创建一个新对象 2.将函数的作用域赋给新对象(this就指向这个对象) 3.执行函数中的代码 4.返回这个对象 根据这个的思路,来实现一个 ...

  8. js中的bind方法的实现方法

    js中目前我遇见的改变作用域的5中方法:call, apply, eval, with, bind. var obj = { color: 'green' } function demo () { c ...

  9. 05_动手动脑之String.equals()方法的实现代码

    Question: 请查看String.equals()方法的实现代码,注意学习其实现方法. Answer: java中的String.equals()方法的实现代码: equals()法是根类Obj ...

随机推荐

  1. RxJS + Redux + React = Amazing!(译一)

    今天,我将Youtube上的<RxJS + Redux + React = Amazing!>翻译(+机译)了下来,以供国内的同学学习,英文听力好的同学可以直接看原版视频: https:/ ...

  2. ES5对Array增强的9个API

    为了更方便的对Array进行操作,ES5规范在Array的原型上新增了9个方法,分别是forEach.filter.map.reduce.reduceRight.some.every.indexOf ...

  3. Android性能优化之巧用软引用与弱引用优化内存使用

    前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ...

  4. 微信小程序IDE(微信web开发者工具)安装、破解手册

    1.IDE下载 微信web开发者工具,本人是用的windows 10 x64系统,用到以下两个版本的IDE安装工具与一个破解工具包: wechat_web_devtools_0.7.0_x64.exe ...

  5. C#发送邮箱

    之前自己从来没有做过发送邮箱的功能,前段时间项目需要,在找了很多帖子之后,终于实现了. 之后有整理了一下,写了一个类.直接给类传递信息,就可以发送了. 这里还需要说明的是,发送邮箱需要开通POP3/S ...

  6. 微信开发 :WeixinPayInfoCollection尚未注册Mch 问题解决

    在使用开源项目 SENPARC.WEIXIN SDK 调用微信支付接口的时候出现了WeixinPayInfoCollection尚未注册Mch,这个问题. 最后地解决方案是: 我这个傻逼忘了在全局Gl ...

  7. .NET面试题集锦①(Part一)

    一.前言部分 文中的问题及答案多收集整理自网络,不保证100%准确,还望斟酌采纳. 1.面向对象的思想主要包括什么? 答:任何事物都可以理解为对象,其主要特征: 继承.封装.多态.特点:代码好维护,安 ...

  8. iOS 原生地图地理编码与反地理编码

    当我们要在App实现功能:输入地名,编码为经纬度,实现导航功能. 那么,我需要用到原生地图中的地理编码功能,而在Core Location中主要包含了定位.地理编码(包括反编码)功能. 在文件中导入 ...

  9. js实现四大经典排序算法

    为了方便测试,这里写了一个创建长度为n的随机数组 function createArr(n) { var arr = []; while (n--) { arr.push(~~(Math.random ...

  10. Markdown学习笔记

    分为两步: 1.阅读Markdown中文官网的文档 2.下载MarkdownPad2将中文官网中文档的例子敲一遍,其中Markdownpad2为官网中推荐的编辑器 备注: 如果只看中文官网文档,不边看 ...