Javascript面试题,整理好咯
中级前端面试题,不低于12k,整理的是js较高频知识点,可能不够完善,大家有兴趣可以留言补充,我会逐步完善,若发现哪里有错,还请多多斧正,哈哈
http和浏览器相关知识点,已分离出,会在下篇整理
数据类型
分为基本类型、引用类型。
基本类型包括undefined、null、string、number、boolean、symbol、bigint;
symbol为es6新增,表示独一无二的值;
bigint表示大整数,防止数值较大时丢失精度;
引用类型为object,包含array、function、date。
undefined、null的区别
undefined表示未定义、没有值,null表示空对象
基本类型、引用类型的区别
内存分为栈内存、堆内存,栈内存先进后出,堆内存先进先出。
基本类型存放在栈内存,引用类型存放在堆内存;
基本类型不可添加属性、方法,而引用类型可以。
数据类型检测方法
typeof:使用简单,但存在缺陷,对引用类型除function外,都返回object;
instanceof:检测对象是否属于某个类,返回布尔值,但不能检测基本类型;
constructor:除undefined、null以外,其他对象的__proto__上都有constructor属性;
Object.prototype.toString.call():终极方案。
数组常用方法
分为改变原数组、不改变原数组两种。
改变原数组:
push:向末尾添加一个;
pop:删除最后一个;
unshift:向开头添加一个;
shit:删除第一个;
sort:不传参时默认为升序,传参可设置升序、降序;
forEach:遍历数组,修改元素,无返回值;
reverse:将数组翻转,倒置;
splice: 可增,删,修改。
注意:splice(index, length, item),index为开始下标,length为删除个数,item为替换项
只传index,会删除index之后(包含index)的所有元素;
传index、length俩参数,会删除掉index之后的length个元素,length为0,则不删除;
传index、length、item三个参数,length为0时,会在index之后添加item;length大于0时,会删除length个,并将item替换进去。
不改变原数组:
jion:将元素以字符拼接,返回字符串;
concat:拼接多个数组;
slice:切割数组,slice(start, end),start为开始下标,end为截止下标(不含end);
map:遍历数组,返回新数组;
filter:查找符合条件的元素,返回新数组;
find:查找符合条件的元素,返回该元素;
findIndex:查找元素首次出现的下标值,并返回下标值;
includes:检查数组是否包含某元素,返回布尔值;
some:检测数组是否有元素满足条件,有一个满足则返回true,并终止;
every:检测数组元素是否都满足条件,都满足返回true,否则false;
reduce:遍历数组,并返回一个最终的构建值(比如累加)。
数组排序
常见排序有sort排序、冒泡排序、选择排序、快速排序。
sort排序:传参可设置升序、降序,不传参时默认为升序;
冒泡排序:for循环嵌套for循环,两两比较,大的放后面;
选择排序:for循环嵌套for循环,先假设下标为0的是最小值,两两对比,小于最小值,则更新下标,并替换最小值;
快速排序:冒泡排序的改进版,设定分界值,根据分界值把数组分为左右两部分,比分界值小的放左边,大的放右边,再递归,最后合并。
数组去重
数组去重常用方法有indexof、filter、for循环、set结构。
indexof:for循环,将下标等于-1的元素push进空数组;
filter:filter的第三个参数self为当前数组,搭配indexof将首次出现的数据筛出来;
for循环嵌套for循环,两两比较,相同则删除;
set结构:es6的new Set()。
闭包
闭包是指能访问并操作其他函数内部变量的函数,由于作用域链的关系,形成了闭包。
闭包使用场景
使用场景:模块化开发、实现回调函数、事件处理、实现递归、实现函数柯里化等。
模块化开发:封装私有变量、私有方法,避免全局命名冲突和变量污染。
事件处理:在循环或定时器等异步操作中,很常用。
实现函数柯里化:柯里化是一种函数编程技术,将多个参数的函数转换为一系列只接受一个参数的函数。闭包可以很好实现柯里化。
闭包优缺点
优点:数据持久化、避免全局变量污染、提高安全性;
缺点:增加内存占用,使用不当会造成内存泄露;过度使用会降低代码可读性,不利于维护。
常见内存泄露
闭包(变量被持久化,不会被回收);
全局变量(相当于挂载到window对象上);
未移除的事件监听或定时器。
防抖、节流
防抖:事件被触发多次,但只生效最后一次;
节流:一段时间内,事件只被实际触发一次;
常见防抖:输入框;常见节流:滚动、表单提交。
this指向
全局上下文:this指向window;
普通函数:this指向它的调用者,没有调用者,则指向window;
箭头函数:没有this,捕获上下文this;
构造函数:this指向自己的实例对象;
事件处理:this指向触发事件的元素本身。
apply、call、bind
三者都可以改变this指向。
call和apply很类似,除第一个参数(需绑定到对象的上下文),call接受的是多个参数对象,而apply接受的是一个数组(包含多个参数对象的数组);
bind会创建新的绑定函数,并包装原函数对象,调用绑定函数通常会执行原函数。
注意:bind无法改变构造函数的this指向。
深拷贝、浅拷贝
作用于引用类型object、array。
浅拷贝只复制了对象的this,没复制本身,新旧对象共享同一个内存,修改新对象会改变原对象;
深拷贝开辟了独立空间,新旧对象不再共享内存,修改新对象不会改变原对象;
浅拷贝实现方法:Object.assign(只有一层结构,是深拷贝)、concat、slice;
深拷贝实现方法:JSON.parse(JSON.stringify()) 、递归循环
JSON.stringify()的缺点
时间对象:序列化和反序列化后,会变成字符串;
正则对象:序列化会变空对象;
函数对象:序列化则会丢失
new操作符
创建空对象;设置原型链;绑定this;继承方法和属性(执行构造函数);返回新对象。
原型、原型链
原型:对象的prototype属性所指向的原型对象;
原型链:原型对象也有自己的原型对象,向下通过__proto__一层层查找,形成了原型链,原型链终点返回null。
原型链的终点为什么是null
原型链上所有节点都是对象,不能是字符串、数字、布尔值等类型;
规范要求原型链必须有限长度。
作用域、作用域链
作用域:变量或方法被访问的有效范围;
作用域有三个:全局作用域,块级作用域,函数作用域;
作用域链:函数执行时查找标识,从当前作用域找到外部,一直到全局作用域,一层层向上查找,形成作用域链。
函数声明、函数表达式
函数声明:是完整语句;在代码执行前创建;未调用也占内存。
函数表达式:是语句的一部分;在代码运行时临时创建;调用完立即释放内存。
事件循环
js运行中处理异步任务和事件的机制。
异步任务分为宏任务、微任务两种,先从宏任务队列取出第一个,当执行宏任务碰到微任务时,把微任务放入微任务队列,执行完当前宏任务,再执行微任务,当所有的微任务都执行完,再从宏任务取下一个执行,如此反复,直到所有任务都执行完成。
微任务:常见的Promise.then,$nextTick;
宏任务:除了微任务,其他都是宏任务,比如setTimeout,setInterval。
事件冒泡、事件委托
事件冒泡:元素接收事件时,会将事件传递给父级,层层传递,直到window;
事件委托:原理为事件冒泡机制;
阻止冒泡事件:click.stop;
阻止默认事件:click.prevent;
事件委托优点:减少事件注册,节省内存;缺点:无需绑定事件的也会被绑定。
js盒模型
分为三种:标准盒模型、IE盒模型、CSS3盒模型。
标准盒模型:由W3C规范定义,元素宽高仅为content,不包含其他(border、padding、margin);
IE盒模型:IE浏览器独有,元素宽高为content+padding+border,不含margin;
CSS3盒模型:CSS3引入的新模型,元素宽高为content+padding+border+margin。
获取、设置元素的宽度和高度:
标准盒模型,使用clientWidth、clientHeight获取元素的内容区宽高;
IE盒模型, 使用offsetWidth、offsetHeight获取元素的实际宽高;
CSS3盒模型,使用getBoundingClientRect()获取元素的实际宽高。
== 和 ===
两者都可判断两个值是否相等。
==没有===严谨;
==在比较不同类型的值时,会先转成同类型(隐式强制转换)再去比较,===则不会。
javascript继承
分为原型链继承、构造函数继承、组合继承、Object.create()、class继承。
原型链继承:最基本的继承方式,每个对象都有一个原型对象,通过原型链将属性、方法传递,子构造函数的原型对象指向父级实例,实现继承。
构造函数继承:子构造函数使用call或apply方法,改变this指向,将父构造函数的上下文设为子对象的上下文,实现继承。
组合继承:结合了原型链继承和构造函数继承。
Object.create():将现有对象属性挂载到新建对象的原型上,实现继承。
class继承:es6引入的类概念,通过class关键字和extends关键字,实现类的继承。
javascript如何处理异常
try...catch...finally:try里放入可能出现异常的代码,catch捕获异常,finally释放资源(无论是否异常,最后都会执行)。
throw关键字:手动抛出异常。
promise中异常:通过catch捕获。
javascript高阶函数
高阶函数需满足特性(接受一个或多个参数、返回一个函数)中至少一个;
优点:使代码更加简洁、易维护;
常见高阶函数:map、filer、find、findexIndex、forEach、some、every、sort等等。
函数柯里化
柯里化是一种函数的转换技术,将函数f(a,b,c)转换成f(a)(b)(c)。
优点:函数职责单一、可复用、
通过箭头函数实现简单例子:
// const sum = x => y => z => x + y + z;
// const total = sum(1)(2)(3);
// console.log(total ); // 输出6
defer、async
两者都是异步执行方案,解决js自上而下同步解析时,可能带来的阻塞。
defer会保证执行顺序,async不能保证。
Dom操作
创建节点:creatElement方法(创建节点)、appendChild方法(末尾插入节点)、cloneNode方法(克隆节点)
删除节点:removeChild方法(删除某个子节点)
获取节点:getElementById、getElementsByTagName、getElementsByClassName、getElementsByName属性(通过name属性获取节点)
查找节点:parentNode属性(查父节点)、childNodes和children属性(查子节点)
CommonJS
是一种模块化规范,将代码分割成一个个模块,每个模块拥有独立作用域。
核心功能:导入(require),导出(exports)。

浙公网安备 33010602011771号