PPs:之前把笔记锁了是因为题目都是我在网上搜的,答案也不一定正确,所以锁起来了,而且也没有写完,今天有站里的朋友来加我想看笔试题,现在就不锁了。不对的或者还没验证的地方还请各位朋友指正,谢谢。
Q1:
在tmall.com的某个页面中存在一个id等于J_iframe_taobao的iframe,该iframe的域名是taobao.com。在不考虑IE浏览器的情况下,用最简洁的代码实现页面与该iframe进行双向通信?
...
<iframe id="J_iframe_taobao" src="http://taobao.com/xxx"></iframe>
...
复制代码
该题应该是考察html5的postMessage。
答案如下(答案是从别的网页搬过来的,po主说可能有误):
var onmessage = function(e) {
var data = e.data,p = document.createElement_x('p');
p.innerHTML = data;
document.getElementById('J_iframe_taobao').appendChild(p);
};
//监听postMessage消息事件
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('message', onmessage, false);
} else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onmessage', onmessage);
}
复制代码
Q2:请写一个 getParents 方法让它可以获取某一个 DOM 元素的所有父亲节点。
Q3:现有代码如下:
function test() {
var a = 1;
setTimeout(function() {
alert(a);
a = 3;
}, 1000);
a = 2;
setTimeout(function() {
alert(a);
a = 4;
}, 3000);
}
test();
alert(0);
复制代码
请注意,代码中有三处alert.他们分别会alert出什么值,时间上的顺序是怎样的?
请详述得到这个答案的原因,特别是test函数的局部变量a是对运行结果的影响。
答案如下:
它们分别会弹出2、3、0,而对应的时间上的顺序是先弹0,再弹2,最后弹3。
原因是因为setTimeout会设置定时器将代码延迟执行,第一个setTimeout里面的函数会在执行test以后2秒执行,第二个setTimeout里面的函数会在执行test以后3秒执行,而alert(0)是在test函数执行以后马上就执行了。所以test函数执行以后a的值变为2,然后执行alert(0)弹出0,过两秒弹出a即2,此时a的值变为3,再过一秒弹出a即3。
Q4:
当我们使用CSS3新属性,比如:box-shadow或者transition时,我们怎么检测浏览器是否支持这些属性?
请设计一个JavaScript函数,该函数接受一个CSS属性名作为参数,并返回一个boolean值,表明浏览器是否支持这个属性。
答案如下(该答案是搬过来的,知识不够还未验证):
var supports = (function() {
var div = document.createElement('div'),
vendors = 'Khtml Ms O Moz Webkit'.split(' '),
len = vendors.length;
return function(prop) {
if ( prop in div.style ) return true;
prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});
while(len--) {
if ( vendors[len] + prop in div.style ) {
// browser supports box-shadow. Do what you need.
// Or use a bang (!) to test if the browser doesn't.
return true;
}
}
return false;
};
})();
if ( supports('textShadow') ) {
document.documentElement.className += ' textShadow';
}
复制代码
Q5:如果你现在使用的是 Google Chrome 或 Apple Safari,如何让 input 元素在默认情况下显示 “alipay WD Team”,而在光标移入后则显示空白?
答案如下:
css3 placeholder必须输入文字才会消失,所以不行,需要用js实现。
// 假设该input元素的id为input
window.onload = function() {
var input = document.getElementById("input");
input.onblur = function() {
this.value = (this.value == '' ? this.defaultValue : this.value);
};
input.onfocus = function() {
this.value = (this.value == this.defaultValue ? '' : this.value);
};
};
复制代码
Q6:预测以下代码的结果并解释原因。
alert(Function instanceof Object);
alert(Object instanceof Function);
复制代码
答案如下(结果是对的,原因太高深看不懂!):
Object, Function, Array等等这些都被称作是构造“函数”,他们都是函数。而所有的函数都是构造函数Function的实例。从原型链机制的的角度来说,那就是说所有的函数都能通过原型链找到创建他们的Function构造函数的构造原型Function.protorype对象,所以:
alert(Object instanceof Function); // return true
复制代码
与此同时,又因为Function.prototype是一个对象,所以他的构造函数是Object. 从原型链机制的的角度来说,那就是说所有的函数都能通过原型链找到创建他们的Object构造函数的构造原型Object.prototype对象,所以:
alert(Function instanceof Object); // return true
复制代码
Q7:现有代码如下:
var foo = 1;
function main(){
alert(foo);
var foo = 2;
alert(this.foo);
this.foo = 3;
}
复制代码
(1)请给出以下两种方式调用函数时,alert的结果,并说明原因。
var m1 = main();
var m2 = new main();
复制代码
答案如下(答案是对的,原因也分析的有理有据,可是第一个alert(foo)不是应该直接就默认的全局变量foo吗?怎么就变成undefined了?!这道题要再想想):
var m1=main()时,alert的结果是undefined和1,原因是首先在alert(foo)的时候,foo在main()函数域内还没有被定义,因此提示undefined,而在输出this.foo时,因为此时的函数执行环境是全局域,相当于window.main(),因此this=window,所以this.foo=window.foo=1
var m2=new main()时,alert的结果是undefined和undefined,第一个undefined的原因与前面一种情况相同,而第二个提示undefined的原因是在这种情况下用new构造了一个main()的实例,因此执行环境发生了改变,不再是全局域,而是m2,因此此时的this=m2,因此this.foo=m2.foo,但是由于在alert(this.foo)时,m2中的this.foo还未被定义,因此提示undefined。
(2)如果想要var m1 = main()产生的m1和前面的m2完全一致,又该如何改造main函数?
答案如下(答案就是错的!):
若要m1=main()与前面的m2产生的效果一致,则main()函数要修改成为function main(){alert(foo);foo=undefined;alert(this.foo);}即可。
Q8:写一段脚本,实现:当页面上任意一个链接被点击的时候,alert出这个链接在页面上的顺序号,如第一个链接则alert(1), 依次类推。
答案如下:
window.onload = function() {
var l = document.links.length;
for (var i = 0; i < l; i++) {
document.links[i].onclick = function(x) {
return function() {
alert(x + 1);
};
}(i);
}
};
复制代码
Q9:(new Date).getTime() 和 +new Date() 都可以取到当前时间戳,它们的实现原理是什么,哪个效率更高?
答案如下(这个答案是搬过来的):
第一种写法所耗的时间基本上只有第二种写法的一半。Date.getTime 这个函数本身实际上等价于 valueOf ,那么结论也呼之欲出了。因为第一种方法实际上直接调用了 valueOf ,而第二种方法涉及到JS内部的类型转换(可以参见网友的这篇文章:【WEB前端】百度前端面试经历小研究1——JavaScript 类型转换),尽管最终的结果也是调用了 valueOf 函数,但是毕竟有个转换的过程,所以效率理应比前者要来的低下吧。
Q10:有一个数组,其中保存的都是小写英文字符串,现在要把它按照除了第一个字母外的字符的字典顺序(字典顺序就是按首字母从a-z顺序排列,如果首字母相同则按第二个字母……)排序,请编写代码:
例:
["abd","cba","ba",]
排序后
["ba","cba","abd"]
答案如下(照搬的,还没验证):
这个题目是专门凸显js函数式编程特点的题目,结果原作者居然用C语言解答了……捂脸。这里给出js的写法,十分简洁明了。
var bySecLetter = function(x, y) {
if (typeof x === 'string' && typeof y === 'string') {
var a = x.slice(1)
, b = y.slice(1)
if (a > b) return 1
else if (a < b) return -1
}
return 0
}
var a = ["abd","cba","ba"]
a.sort(bySecLetter)
复制代码
这里只需要调用sort的比较函数,大于返回正数,小于返回负数,等于返回0即可。而作为字符串,本身的比较顺序就是字典顺序,所以只需要截取从第二个字符开始的字串进行比较,就可以得出比较结果。更多关于sort函数的信息可以参见MDN。
Q11:
(1)你了解arguments对象么,它有哪些属性?
答案如下(大部分的文章都只介绍了这4种属性,不知道有没有caller属性,答案引自【JS入门之arguments对象 】):
0…n 属性;
argument属性:为当前执行的 function 对象返回一个arguments 对象,function 参数是当前执行函数的名称,可以省略;
length 属性:包含了传递给函数的参数的数目;
callee属性:返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文,callee 属性仅当相关函数正在执行时才可用,callee 属性的初始值就是正被执行的 Function 对象。
(2)arguments是数组么?如果不是请写一段代码将其转化为真正的数组,什么情况下需要这么做?
答案如下(代码是搬的,不知道对不对):
arguments对象不是数组,
function A(){
var Args = Array.prototype.slice.call(arguments, 0);
B(Args.slice(1));
}
复制代码
(3)arguments有什么特性,可以用这些特性做什么?
答案如下:
Q12:请为JavaScript每个Array对象添加一个类似于PHP的shuffle()的方法。
答案如下(搬的):
var data = new Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
if (!Array.prototype.shuffle) {
Array.prototype.shuffle = function() {
for(var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x);
return this;
};
}
alert(data.shuffle());
复制代码