经典的js题库(常见的js面试题以及答案分析)
1.
function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);} //请写出以下输出结果: Foo.getName(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); new new Foo().getName(); //答案: Foo.getName();//2 getName();//4 Foo().getName();//1 getName();//1 new Foo.getName();//2 new Foo().getName();//3 new new Foo().getName();//3
// 没有5的原因:
function Foo() { getName = function () { alert (1); }; return this; } var getName;//只提升变量声明 function getName() { alert (5);}//提升函数声明,覆盖var的声明 Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; getName = function () { alert (4);};//最终的赋值再次覆盖function getName声明 getName();//最终输出4
//为什么第2个和第4个getName()输出的不一样
Foo函数的第一句 getName = function () { alert (1); }; 是一句函数赋值语句,注意它没有var声明,所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是第二问中的alert(4)函数,将此变量的值赋值为 function(){alert(1)}。
// 优先级
(.)的优先级高于new操作,
于是 new (Foo.getName)();遂弹出2。
于是(new Foo()).getName();(new Foo())在FoO上没有在原型上找到getName(),遂弹出3
于是new (((new Foo()).getName)());遂弹出3
2.
var arr = [],
arr2 = {};
console.log(typeof(arr) === typeof(arr2)); // true
上方利用typeof比较数组和对象,因为typeof获取NULL、数组、对象的类型都为object,所以console为true。
var arr = [],
arr2 = [];
console.log(arr === arr2); // false
上方两个相同的数组比较,因为两个单独的数组永不相等,所以console为false。
var arr = [];
console.log(arr instanceof Object); // true
console.log(arr instanceof Array); // true
上方利用instanceof判断一个变量是否属于某个对象的实例,因为在JavaScript中数组也是对象的一种,所以两个console都为true。
3
var elem = document.getElementsByTagName('div'); // 如果页面上有5个div
for(var i = 0; i < elem.length; i++) {
elem[i].onclick = function () {
alert(i); // 总是5
};
}
上方是一个很常见闭包问题,点击任何div弹出的值总是5,因为当你触发点击事件的时候i的值早已是5,可以用下面方式解决:
var elem = document.getElementsByTagName('div'); // 如果页面上有5个div
for(var i = 0; i < elem.length; i++) {
(function (w) {
elem[w].onclick = function () {
alert(w); // 依次为0,1,2,3,4
};
})(i);
}
在绑定点击事件外部封装一个立即执行函数,并将i传入该函数即可。
4.
for(var i=0;i<3;i++){
setTimeout(funcation(){
console.log(i)
},1000)
}
//=> 3次3
原因:定时器是一次执行函数,当执行for循环时候,并没有执行定时器中的闭包函数,当1s之后,触发闭包函数,但是for循环已经执行完毕,i等于3了
for(let i=0;i<3;i++){
setTimeout(funcation(){
console.log(i)
},1000)
}
//=> 0,1,2
原因:for循环使用let定义变量,let是块变量,定时器中的闭包函数通过var是无法传到函数内部的,但是通过let声明的块声明变量,变量的作用域就是这个快
5.
async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
setTimeout(function(){
console.log('setTimeout')
},0);
async1();
new Promise(function(resolve){
console.log('promise1');
resolve();
}).then(function(){
console.log('promise2')
});
console.log('script end')
答案:
script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout
// async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。 可以理解为,是让出了线程,跳出了async 函数体
- 经典面试题分析之归并排序的实现(js实现)
- Java经典50道线程面试题以及答案
- android 常见面试题以及答案
- 15道Java 经典面试题及答案分析
- jsp及Servlet经典面试题以及答案
- 五个经典面试题及答案分析
- 比较常见的数据库SQL面试题以及答案
- jsp及Servlet经典面试题以及答案
- android 常见面试题以及答案
- selenium 常见面试题以及答案
- 前端面试题以及常见问题与答案(Ajax持续更新ing......)
- 前端面试题以及常见问题与答案(HTML和CSS部分持续更新ing......)
- jsp及Servlet经典面试题以及答案
- OC 常见面试题以及答案
- android 常见面试题以及答案
- 【收藏】15道Java 经典面试题及答案分析
- C/C++程序员应聘时常见的面试题和分析答案(一)
- ajax的经典面试题以及答案
- 经典面试题分析之Google搜索之星(js实现)
- C/C++程序员应聘时常见的面试题和分析答案(二)