前言:今年受疫情影响,大多数企业都收缩了HC,有的企业甚至关门大吉。这样的情境下,找工作就变得比往年困难。但是,只要你不断努力,消掉自我怀疑情绪,工作总会有的,相信我!我搜集了腾讯、快手、头条、美团、滴滴等各大公司的前端面试题整理成知识点,有自己亲身经历的,也有身边朋友分享给我的。希望对正在找工作的你有所帮助,也衷心的祝愿大家都能找到心仪的工作。
一、项目地址
二、面试题集锦
javascript基础知识点及常考面试题
1、let、const、var 的区别?
let 和 const 定义的变量不会出现变量提升,而 var 定义的变量会提升。
let 和 const 是JS中的块级作用域
let 和 const 不允许重复声明(会抛出错误)
let 和 const 定义的变量在定义语句之前,如果使用会抛出错误(形成了暂时性死区),而 var 不会。
const 声明一个只读的常量。一旦声明,常量的值就不能改变(如果声明是一个对象,那么不能改变的是对象的引用地址)
一道鹅厂面试题:问输出什么?
for(var i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i)
}, 0)
}
结果:输出10个10. 解决方案有哪些? (可以使用let替换var、或者使用闭包)
2、typeof、instanceof 的区别?instanceof 的实现原理是什么?
typeof:
能够正确判断基本类型,null除外, 'tyoeof null' 输出为 'object'。
不能正确的判断引用类型,typeof 应用于函数输出 'function',除此之外,输出的全是 object。
instanceof:
可以准确的判断复杂数据类型,但是不能正确判断基本数据类型。
instanceof 是通过原型链判断的,A instanceof B, 在A的原型链中层层查找,是否有原型等于B.prototype,如果一直找到A的原型链的顶端(null;即Object.proptotype.__proto__),仍然不等于B.prototype,那么返回false,否则返回true.
移步我的博客:instanceof原理
3、ES6中的 class 和ES5的类有什么区别?
我的博客:浅谈ES5,ES6继承
4、js同步异步的理解
我的博客:了解JavaScript执行机制
5、this的指向
我的博客:this指向的4种场景
6、call、apply、bind的区别,内部原理?
我的博客:Javascript中的apply、call和bind
7、new操作符原理
new 操作符的工作原理:
1、创建一个空对象,var obj = {};
2、将新创建对象obj的__proto__指向构造函数原型prototype
3、将新对象obj作为调用上下文,执行构造函数
4、如果构造函数中没有返回其它对象,那么返回新创建对象obj,否则返回构造函数的返回值
8、谈谈你对原型和原型链的理解?附上一道鹅厂的题:
var foo = {},
F = function(){};
Object.prototype.a = 'value a';
Function.prototype.b = 'value b';
console.log(foo.a)
console.log(foo.b)
console.log(F.a)
console.log(F.b)
输出结果:
console.log(foo.a) // value a
console.log(foo.b) // undefined
console.log(F.a) // value a
console.log(F.b) // value b
这题考察原型链知识,理解原理移步我的博客-:原型链
9、深拷贝和浅拷贝区别?
浅拷贝:只是复制对象的第一层属性,如果对象的属性是引用类型时,实质复制的是其引用,只要引用指向的值改变就会跟着改变
深拷贝:对于对象中的属性进行递归复制,如果对象的属性是引用类型时进行递归,直到递归至基本类型时进行赋值,深拷贝的对象不随源对象变化。
实现一个深拷贝:
function deepClone(obj) { //递归拷贝
if(obj === null) return null; //null 的情况
if(obj instanceof RegExp) return new RegExp(obj);
if(obj instanceof Date) return new Date(obj);
if(typeof obj !== 'object') {
//如果不是复杂数据类型,直接返回
return obj;
}
/**
* 如果obj是数组,那么 obj.constructor 是 [Function: Array]
* 如果obj是对象,那么 obj.constructor 是 [Function: Object]
*/
let t = new obj.constructor;
for(let key in obj) {
//如果 obj[key] 是复杂数据类型,递归
t[key] = deepClone(obj[key]);
}
return t;
}
10、防抖和节流的实现
防抖(debounce): 指定时间内频繁触发事件,则时间清零重新计时,只有当触发频率超过指定时间间隔才会执行函数。
节流(throttle): 一段时间内只会执行一次函数。
防抖实现:
function debounce(func, wait, immediate = true) {
let timer;
// 延迟执行函数
const later = (context, args) => setTimeout(() => {
timer = null;// 倒计时结束
if (!immediate) {
func.apply(context, args);
//执行回调
context = args = null;
}
}, wait);
let debounced = function (...params) {
let context = this;
let args = params;
if (!timer) {
timer = later(context, args);
if (immediate) {
//立即执行
func.apply(context, args);
}
} else {
clearTimeout(timer);
//函数在每个等待时延的结束被调用
timer = later(context, args);
}
}
debounced.cancel = function () {
clearTimeout(timer);
timer = null;
};
return debounced;
};
节流实现:
//underscore.js
function throttle(func, wait, options) {
var timeout, context, args, result;
var previous = 0;
if (!options) options = {};
var later = function () {
previous = options.leading === false ? 0 : Date.now() || new Date().getTime();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
var throttled = function () {
var now = Date.now() || new Date().getTime();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
// 判断是否设置了定时器和 trailing
timeout = setTimeout(later, remaining);
}
return result;
};
throttled.cancel = function () {
clearTimeout(timeout);
previous = 0;
timeout = context = args = null;
};
return throttled;
};
11、ES6新的特性有哪些?
块级作用域(let,const)、基本数据类型Symbol
定义类的语法糖(class)
变量的解构赋值
箭头函数、函数参数允许设置默认值,引入了rest参数
数组新增了一些API,如 isArray / from / of 方法;数组实例新增了 entries(),keys() 和 values() 等方法
对象和数组新增了扩展运算符
ES6 新增了模块化(import/export)
ES6 新增了 Set 和 Map 数据结构
ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例
ES6 新增了生成器(Generator)和遍历器(Iterator)
12、对promise的理解,手写代码
我的博客-手撸Promise
13、打开一个网页浏览器做了哪些工作
这道题是面试中的高频题,可以考察的知识点非常多。主要包括了以下几个流程:
- 浏览器的地址栏输入URL并按下回车。
- 浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
- DNS解析。
- 建立TCP连接(三次握手)。
- HTTP发起请求。
- 服务器处理请求,浏览器接收HTTP响应。
- 渲染页面,构建DOM树。
- 关闭TCP连接(四次挥手)。
再针对每个过程进行详细考察。
(1)DNS解析过程,网上找了一张图,过程画的比较直观清晰:
(2)浏览器渲染过程
移步我的博客:浏览器渲染过程
(3)TCP的三次握手和四次挥手过程?
(4)你知道HTTP哪些状态码?
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分别表示什么请自行查找)。
(5)浏览器缓存和缓存原理 详细参看博客:
三、面试技巧
我认为对于技术面试,除了准备基础知识点外,也需要准备一些面试技巧,下面列出我网上找的有参考价值的帖子:
四、写在最后
本文梳理了JavaScript的基础知识面试题,后续还会梳理出算法、框架等的面试题,持续更新中。。。 如果本文给了您一点帮助或者是启发,请不要吝啬你的赞和Star,您的肯定是我前进的最大动力。