js面试题
1 js数据类型
基本数据类型
Number String Boolean Null Undefined Symbol bigInt
引用数据类型
object Array Date Function RegExp
2 js变量和函数声明的提升
在js中变量和函数的声明会提升倒最顶部执行
函数的提升高于变量的提升
函数内部如果用var声明了相同名称的外部变量,函数将不再向上寻找
匿名函数不会提升
3 闭包
闭包就是能够读取其他函数内部变量的函数
闭包基本上就是一个函数内部返回一个函数
好处
可以读取函数内部的变量
将变量始终保持在内存中
可以封装对象的私有属性和私有方法
坏处
比较耗费内存 使用不当会造成内存溢出的问题
4 ==和===的区别
==是非严格意义上的相等
===是严格意义上的相等,会比较两边的数据类型和值的大小
5 this
this总是指向函数的直接调用者
如果有new关键字 this指向new出来的对象
在事件中 this指向触发这个事件的对象
6 js数组和对象的遍历方式
for in
for
forEach
for-of
7 map和forEach的区别
forEach方法,是最基本的方法,就是遍历与循环,默认有3个传参:分别是遍历的数组内容item 数组索引 index 和 当前遍历数组Array
map方法 基本用法和foreach一致,但是不同的,它会返回一个新的数组,所有callback需要有return值 如果没有 会返回undefinded
8 箭头函数与普通函数的区别?
函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
不可以使用arguments对象,该对象在函数体内不存在,如果要用,可以用Rest参数代替
不可以使用yiekd命令,因此箭头函数不能用作Fenerator函数
9 同源策略
同源指的是域名、协议、端口号相同
10 如何解决跨域
jsonp跨域
document.domain+iframe跨域
nodejs中间件代理跨域
后端在头部信息里面设置安全域名
11 严格模式的限制
变量必须声明后再使用
函数的参数不能有同名属性,否则报错
不能使用with语句
禁止this指向全局对象
12 es6新增
新增模板字符串
箭头函数
for-of
ES6将promise对象纳入规范,提供了原生的promise对象
新增let和const命令
13 attribute 和 property 的区别是什么?
attribute 是 dom 元素在文档中作为 html 标签拥有的属性
property 就是 dom 元素在 js 中作为对象拥有的属性。
对于 html 的标准属性来说,attribute 和 property 是同步的,是会自动更新的
但是对于自定义的属性来说,他们是不同步的
14 let和const 的区别是什么?
let 命令不存在变量提升,如果在 let 前使用,会导致报错
如果块区中存在 let 和 const 命令,就会形成封闭作用域
不允许重复声明
const定义的是常量,不能修改,但是如果定义的是对象,可以修改对象内部的数据
15 内存泄漏
- 定义:程序中己动态分配的堆内存由于某种原因程序未释放或无法释放引发的各种问题。
- js中可能出现的内存泄漏情况:结果:变慢,崩溃,延迟大等
- js中可能出现的内存泄漏原因
- 全局变量
- dom 清空时,还存在引用
- 定时器未清除
- 子元素存在引起的内存泄露
16 script 引入方式?
- html 静态 <script> 引入
- js 动态插入 <script>
- <script defer> : 异步加载,元素解析完成后执行
- <script async> : 异步加载,但执行时会阻塞元素渲染
17 数组(array)方法
map : 遍历数组,返回回调返回值组成的新数组
forEach : 无法 break ,可以用 try/catch 中 throw new Error 来停止
filter : 过滤
some : 有一项返回 true ,则整体为 true
every : 有一项返回 false ,则整体为 false
join : 通过指定连接符生成字符串
push / pop : 末尾推入和弹出,改变原数组, 返回推入/弹出项
unshift / shift : 头部推入和弹出,改变原数组,返回操作项
sort(fn) / reverse : 排序与反转,改变原数组
concat : 连接数组,不影响原数组, 浅拷贝
slice(start, end) : 返回截断后的新数组,不改变原数组
splice(start,number,value…): 返回删除元素组成的数组,value 为插入项,改变原数组
indexOf / lastIndexOf(value, fromIndex) : 查找数组项,返回对应的下标
reduce / reduceRight(fn(prev, cur) ,defaultPrev) : 两两执行,prev 为上次化简函数的return 值,cur 为当前值(从第二项开始)
18 JavaScript 深浅拷贝?
浅拷贝
Object.assign
深拷贝
可以通过 JSON.parse(JSON.stringify(object)) 来解决
19 说说异步编程的实现方式?
回调函数
优点:简单、容易理解
缺点:不利于维护、代码耦合高
事件监听
优点:容易理解,可以绑定多个事件,每个事件可以指定多个回调函数
缺点:事件驱动型,流程不够清晰
发布/订阅(观察者模式)
类似于事件监听,但是可以通过‘消息中心’,了解现在有多少发布者,多少订阅者
Promise 对象
优点:可以利用 then 方法,进行链式写法;可以书写错误时的回调函数
缺点:编写和理解,相对比较难
Generator 函数
优点:函数体内外的数据交换、错误处理机制
缺点:流程管理不方便
async 函数
优点:内置执行器、更好的语义、更广的适用性、返回的是 Promise、结构清晰
缺点:错误处理机制
20 说说面向对象编程思想?
基本思想是使用对象,类,继承,封装等基本概念来进行程序设计
优点
易维护
易扩展
开发工作的重用性、继承性高,降低重复工作量。
缩短了开发周期
21 项目性能优化
减少 HTTP 请求数
减少 DNS 查询
使用 CDN
避免重定向
图片懒加载
减少 DOM 元素数量
减少 DOM 操作
使用外部 JavaScript 和 CSS
压缩 JavaScript、CSS、字体、图片等
优化 CSS Sprite
使用 iconfont
多域名分发划分内容到不同域名
尽量减少 iframe 使用
避免图片 src 为空
把样式表放在 link 中
把 JavaScript 放在页面底部
22 什么是单线程,和异步的关系?
单线程 :只有一个线程,只能做一件事
原因 : 避免 DOM 渲染的冲突
浏览器需要渲染 DOM
JS 可以修改 DOM 结构
JS 执行的时候,浏览器 DOM 渲染会暂停
两段 JS 也不能同时执行(都修改 DOM 就冲突了)
webworker 支持多线程,但是不能访问 DOM
解决方案 :异步
23 说说负载均衡?
单台服务器共同协作,不让其中某一台或几台超额工作,发挥服务器的最大作用
http 重定向负载均衡:调度者根据策略选择服务器以 302 响应请求,缺点只有第一次有效果,后续操作维持在该服务器 dns 负载均衡:解析域名时,访问多个 ip 服务器中的一个(可监控性较弱)原因 - 避免 DOM 渲染的冲突
反向代理负载均衡:访问统一的服务器,由服务器进行调度访问实际的某个服务器,对统一的服务器要求大,性能受到 服务器群的数量
24 作用域链?
作用域链可以理解为一组对象列表,包含 父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数
25 什么是原型、原型链、继承?
所有的函数都有prototype属性(原型)
所有的对象都有__proto__属性
在Javascript中,每个函数都有一个原型属性prototype指向自身的原型,而由这个函数创建的对象也有一个proto属性指向这个原型,而函数的原型是一个对象,所以这个对象也会有一个proto指向自己的原型,这样逐层深入直到Object对象的原型,这样就形成了原型链。
26 逐进增强和优雅降级
逐进增强
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高版本浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容