无论你要应聘的职位是初级、中级还是高级;js基础都是必须要考察的一项硬技能。只有js基础扎实了,才能更出色的完成开发任务和技能的提升。
下面我会尽量全面的涵盖要考察的知识点(作用域、闭包、算法、原型链等)。以题目:答案+解析的方式总结给大家。
话不多说,来看下我亲历的一些面试题。
PS:水平有限,我可以保证的是所有的答案都经过验证。是正解但不一定是最优解。所以欢迎各位大佬指导或补充。
题目1:
function b(){
console.log(a);
}
function c(){
var a = 'world';
b();
}
c();
---------------------------------------
var a = 'hello';
function c(){
var a = 'world';
function b(){
console.log(a);
}
b();
}
c();
问:c()运行结果分别输出什么?解析:
本题考察的知识点:'js作用域'
Javascript采用的是词法作用域(静态作用域),所以它的函数的作用域在函数定义的时候就决定了;
与词法作用域相对的是动态作用域,它的函数的作用域是在函数调用的时候才决定的。
关键词:'定义的时候'
b()执行时要输出a,因此要在b定义的作用域去找a。
上面的b定义时,a的值为'hello';下面b定义时,a的值为'world'。
因此,前者输出'hello'; 后者输出'world'。 题目2:
var a = [];
for(var i = 0; i < 5; i++){
a.push(function(){return console.log(i)})
}
问:a[0]();a[1]();会得到什么结果?解析
本题考察的知识点:'js作用域--全局作用域、块级作用域、闭包';
1、这段代码中i是个全局变量。
2、push进去的匿名函数在for循环结束后调用
3、循环结束后i的值已变为5,因此循环外执行函数,得到的结果永远是5
'如何得到输出结果与序号相等?即:a[0]()==>0;a[1]()==>1……'
答案1
for(let i = 0; i < 5; i++){
a.push(function(){return console.log(i)})
}1、let声明i,将i的作用域限制在for循环内;
2、闭包可以记住自己的作用域
答案2
for(var i = 0; i < 5; i++){
a.push(function(){return console.log(i)});
a[i]();
}
循环内部调用,此时i还未被重新赋值。
'相似的题型(这道题非常经典随处可查到解析):'
for(var i = 0; i < 5; i++){
setTimeout(function(){
console.log(i)
},0)
}
输出结果:5次5
实现分别输出0,1,2,3,4的方法
答案1:
for(let i = 0; i < 5; i++){
setTimeout(function(){
console.log(i)
},0)
}
答案2:
for(var i = 0; i < 5; i++){
(function(j){
setTimeout(function(){
console.log(j)
},0) })(i)
}
我看到的最好的题目变型和解析:https://juejin.cn/post/6844903474212143117
题目3:
var m = true;
setTimeout(function(){
m = false;
},3000);
while(m){};
alert(1);
'请问什么时候弹出1?'
解析:
本题考察的知识点:'event loop、while循环'
这里抛出一个链接来学习一个event loop:
http://latentflip.com/loupe/?code=dmFyIG0gPSB0cnVlOw0Kc2V0VGltZW91dChmdW5jdGlvbigpew0KICAgIG0gPSBmYWxzZTsNCn0sMzAwMCk7DQp3aGlsZShtKXt9Ow0KYWxlcnQoMSk7!!!Y29uc29sZS5sb2coJ3N0YXJ0Jyk7CglzZXRUaW1lb3V0KCgpPT57Cgljb25zb2xlLmxvZygnY2hpbGRyZW4yJyk7CglQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpPT57Cgljb25zb2xlLmxvZygnY2hpbGRyZW4zJykKCX0pCn0sMCkKbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSxyZWplY3QpewoJY29uc29sZS5sb2coJ2NoaWxkcmVuNCcpCglzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7CgkJY29uc29sZS5sb2coJ2NoaWxkcmVuNScpCgkJcmVzb2x2ZSgnY2hpbGRyZW42JykKCX0sMCkKfSkudGhlbigocmVzKT0%2BewoJY29uc29sZS5sb2coJ2NoaWxkcmVuNycpCglzZXRUaW1lb3V0KCgpPT57Cgljb25zb2xlLmxvZyhyZXMpCgl9LDApCn0p
只要理解了时间循环机制,上面的问题答案就很容易得到了。
while循环是个同步语句,同步循环未结束就一直无法出栈,下一段同步代码alert就无法执行。就更别说setTImeout了。
setTimeout是异步语句属于宏任务。会一直在任务队列里等待,无法入栈。
因此这个代码会选入死循环,'永远无法弹出1'。
下面是event loop的经典题目:
console.log('start');
setTimeout(()=>{
console.log('children2');
Promise.resolve().then(()=>{
console.log('children3')
})},0)
new Promise(function(resolve,reject){
console.log('children4');
setTimeout(function(){
console.log('children5');
resolve('children6');
},0)
}).then((res)=>{
console.log('children7');
setTimeout(()=>{
console.log(res);
},0)
})
答案我就不写啦,自己cope代码在浏览器上执行看看得到的结果跟你的答案一不一样吧
ps:这也是一道面试题哦。题目4:手写一个深拷贝
解析:
本题考察的知识点:'js的数据类型、检测数据类型的方法及区别、函数的递归'下面是我封装的deepClone函数:
function deepClone(data){
if(typeof data !== 'object' || data === null){
return data;
}
var newData;
if(data instanceof Array){
newData = [];
if(!data.length){
return newData; }
for(var i = 0; i < data.length; i++){
newData[i] = deepClone(data[i]);
}
}
if(data instanceof Object){
newData = {}; if(!Object.keys(data).length){
return newData;
}
for(var key in data){
newData[key] = deepClone(data[key]);
}
}
return newData;
}
'js数据类型:'
基本数据类型(Number、String、Undefined、Null)
复杂数据类型/引用数据类型(Function、Array、Object)
'检测数据类型的方法及区别:'
1、typeof 检测不出Array类型。Arry识别为objec
2、instanceof 不能用于监测基本类型值
3、constructor 不能检测null和undefined
4、Object.prototype.toString.call 可检测出所有数据类型
给个文章,写的挺详细:https://blog.csdn.net/weixin_40690385/article/details/81509543题目5:
写一个函数:遍历一个数组,如果数组中的某两项相加等于另一项输出true,否则输出false;如 a1=[1,5,6]可输出true;a2=[3,4,5,0,6]只能输出false。
本题考察的知识点:'函数的封装、简单的算法'
function fn(arr){
if(!arr || arr.constructor !== Array){
return;
}
for(var i = arr.length-1; i>=2; i--){
for(var j = arr.length-2;j>=1; j--){
for(var k = arr.length-3; k >=0; k--){
if(i != j && i!= k && j != k){
if(arr[k] + arr[j] === arr[i]){
console.log(true);
}else{
console.log(false)
}
}
}
}
}
}
感觉不是最佳答案,我的解题思路往往不够高阶。欢迎提出新方案