本文深入解析两道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程序设计有所帮助。