JavaScript搜狐面试题解析:数组对象遍历与类实现

作者:闭包旅人时间:2026-10-21 18:23:05浏览:524

本文深入解析两道JavaScript搜狐面试题。第一题要求实现遍历数组或对象的迭代器,重点考察类型判断、this指向控制及break/continue逻辑处理。第二题要求实现包含attr、words、say方法的Man类,涉及构造函数与实例化差异。文章提供思路分析与代码实现参考,帮助开发者理解JS核心机制。

本文分享了几道来自搜狐的JavaScript面试题,旨在帮助读者理解相关知识点并参考具体实现方案。

实现数组与对象遍历迭代器

第一题要求实现一个能够遍历数组或对象中所有成员的迭代器函数。


var each = function(obj, fn){
    //+++++++++++答题区域+++++++++++
    //+++++++++++答题结束+++++++++++
};
try{
    var data1 = [4,5,6,7,8,9,10,11,12];
    var data2 = {
        "a": 4,
        "b": 5,
        "c": 6
    };
    console.group(data1);
    each(data1, function(o){
        if( 6 == this )
            return true;
        else if( 8 == this )
            return false;
        console.log(o + ": \"" + this + "\"");
    });
    console.groupEnd();
    /*------[执行结果]------
    1: "4"
    2: "5"
    4: "7"
    ------------------*/
    console.group(data2);
    each(data2, function(v, n){
        if( 5 == this )
            return true;
        console.log(n + ": \"" + v + "\"");
    });
    console.groupEnd();
    /*------[执行结果]------
    a: "4"
    c: "6"
    ------------------*/
}catch(e){
    console.error("执行出错,错误信息: " + e);
}

【思路分析】

1. 首先需要判断传入的参数是数组还是普通对象。在JavaScript中,可以使用typeof和instanceof来检测变量类型,两者在用法和适用场景上存在区别。

typeof(obj):typeof运算符通常用于返回基本数据类型,但对于引用类型(如数组、对象)往往只返回object。

obj instanceof Array:instanceof运算符主要用于验证一个对象是否属于特定的类或构造函数。

注意:typeof在处理null、数组和普通对象时,均会返回object类型,因此仅靠typeof无法准确区分数组与对象。


var each = function(obj, fn){
  if(obj instanceof Array){
  }
  else if(obj instanceof Object){
  }
};

2. 遍历数组与遍历对象在实现逻辑上存在差异。

遍历数组通常使用基于索引的for循环。


for(var i=0,j=array.length;i<j;i++){
  alert(array[i]);
}

遍历对象则通常使用for...in循环来枚举属性。


for(var e in data){
  alert(data[e]);
}

3. 结果分析


each(data1, function(o){
  if( 6 == this )
    return true;      //表示跳过并继续遍历
  else if( 8 == this )
    return false;     //表示停止遍历
  console.log(o + ": \"" + this + "\"");
});

如果直接使用for循环,会输出数组的所有元素。题目中提供了一个each函数,需要让其内部逻辑指向obj中的具体元素,即通过改变this的指向,使this代表当前遍历到的元素obj[i]。

fn.call(obj[i], i+1):这里fn是each函数的第二个参数(回调函数)。通过call方法,将this绑定为obj中的元素,并将i+1作为第一个参数传入。

仅执行上述操作会输出4,5,7,8,9,10,11,12。因此,还需要在回调函数中增加逻辑,当遇到值为8的元素时,跳出整个循环。


if(obj instanceof Array){
  for(var i=0,j=obj.length;i<j;i++){
    var temp=fn.call(obj[i],i+1);
    if(temp===false){    //===值和类型都要等,==只是值相同null==false
      return;
    }
  }
}

同理,遍历对象的逻辑也需遵循类似的处理方式。


else if(obj instanceof Object){
  for(var e in obj){
    fn.call(obj[e],obj[e],e);    //第一个参数v(对象值),第二个n(对象索引)
  }
}

注意:判断obj instanceof Object的代码必须放在obj instanceof Array之后。因为数组也是对象的一种,如果先判断Object,数组会被归类为普通对象,导致后续的数组特有逻辑无法执行。

实现包含attr、words、say方法的Man类

第二题要求实现一个名为Man的类,该类需包含attr、words、say三个方法。


var Man;
//+++++++++++答题区域+++++++++++
//+++++++++++答题结束+++++++++++
try{
    var me = Man({ fullname: "小红" });
    var she = new Man({ fullname: "小红" });
    console.group();
    console.info("我的名字是:" + me.attr("fullname") + "\n我的性别是:" + me.attr("gender"));
    console.groupEnd();
    /*------[执行结果]------
    我的名字是:小红
    我的性别是:<用户未输入>
    ------------------*/
    me.attr("fullname", "小明");
    me.attr("gender", "男");
    me.fullname = "废柴";
    me.gender = "人妖";
    she.attr("gender", "女");
    console.group();
    console.info("我的名字是:" + me.attr("fullname") + "\n我的性别是:" + me.attr("gender"));
    console.groupEnd();
    /*------[执行结果]------
    我的名字是:小明
    我的性别是:男
    ------------------*/
    console.group();
    console.info("我的名字是:" + she.attr("fullname") + "\n我的性别是:" + she.attr("gender"));
    console.groupEnd();
    /*------[执行结果]------
    我的名字是:小红
    我的性别是:女
    ------------------*/
    me.attr({
        "words-limit": 3,
        "words-emote": "微笑"
    });
    me.words("我喜欢看视频。");
    me.words("我们的办公室太漂亮了。");
    me.words("视频里美女真多!");
    me.words("我平时都看优酷!");
    console.group();
    console.log(me.say());
    /*------[执行结果]------
    小明微笑:"我喜欢看视频。我们的办公室太漂亮了。视频里美女真多!"
    ------------------*/
    me.attr({
        "words-limit": 2,
        "words-emote": "喊"
    });
    console.log(me.say());
    console.groupEnd();
    /*------[执行结果]------
    小明喊:"我喜欢看视频。我们的办公室太漂亮了。"
    ------------------*/
}catch(e){
    console.error("执行出错,错误信息: " + e);
}

思路分析:

1. 首先定义一个构造函数。


Man=function(info){
};

2. 在构造函数内部或原型上定义所需的方法,并处理属性访问与设置逻辑。


var me = Man({ fullname: "小红" });
var she = new Man({ fullname: "小红" });

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述的面试题解析对大家学习JavaScript程序设计有所帮助。

作者最新文章