参考链接:
面试题的思考:
拿到面试题 首先看 考点
题会变 考点不变 不变应万变
高效学习三部曲:
找准知识体系
刻意训练
及时反馈
建立知识体系
JS 基础语法
变量类型和计算
值类型
1 | null |
引用类型
1 | Array |
typeof
深拷贝
变量计算
if 语句中判断的就是以下两种:
truly 变量: !!a === true
falsely 变量:!!a === false
1 | // 以下为 falsely变量,其他都是truly变量 |
关于 ==
转换规则:
1.如果一项操作数是布尔值,在比较之前转换为数值,
false => 0
,true => 1
2.如果一项操作数是字符串,另外一个是数值,在比较之前将字符串转换为数值
3.如果一项操作数是对象,另外一个不是,调用对象的
valueOf()
方法,用得到的基本类型按照前面的规则比较,如果没有则调用toString()
方法4.null 和 undefined 是相等
5.在比较相等之前,不能将 null 和 undefined 转换为其他任何值
6.如果一项操作数是 NaN,相等返 fasle ,不相等返 true。即使两个操作数都是 NaN 类型的,相等还是返 fasle ,因为 NaN 不等于 NaN
7.如果两个操作数都是对象,则比较它们是不是同一个对象,如果两个操作数都指向同一个对象,那操作符返 true,否则为 false
ps:{} 和 [] 是 引用类型,引用类型是存放在堆内存里的,栈内存有一个或者多个地址 指向这个堆内存对应的数据,所以 引用类型在进行 == 操作符时,比较的是地址,而不是真实的值。
关于 ![] == [] 返回true
则 !{} == {} 返回false
的问题
![] == [] 返回true
的推导过程:
根据运算符规则 ,!
是大于 ==
,所以先执行 ![]
首先 !
可将变量转换成 boolean 类型,null、 undefind、’’、 NaN 取反为 true,其他都为 false。
也就是 ![] == []
相当于 false == []
根据规则一 ,false => 0
那么 false == []
相当于 0 == []
在根据规则三 , [].toSting() => ''
为空字符串
则转换成 0 == ''
在根据规则二 Number('') => 0
则 0 == 0
结果自然为 true 啦
!{} == {} 返回false
则是以下的推导过程:
!{} == {}
==> false == {}
==> 0 == {}
==> 0 == {}.toString()
==> 0 == [object object]
==> false
===
: 严格模式下使用 仅比较不转换
1 | '5' == 5 // true |
原型和原型链
class 和继承
类型判断 instanceof
原型和原型链
作用域和闭包
知识点:
作用域分以下三种:
全局作用域
函数作用域
块级作用域
自由变量
一个变量在当前作用域没有定义 但被使用了
就会向上级作用域 一层一层依次查找 直到找到为止
如果到全局作用域中还没找到 就会报 xx is not defined
闭包
闭包:能够访问另外一个函数作用域的变量的函数
作用域的特殊情况:
- 函数作为参数传递
1 | function print(fn) { |
- 函数作为返回值被返回
1 | function create() { |
重点:
所有自由变量的查找,都在函数定义的地方,向上级作用域查找,不是在函数执行的地方
this
this 的使用场景分:
- 作为普通函数
1 | function fn1() { |
- 使用 call apply bind
1 | fn.call({ x: 100 }, a1, a2, a3) // {x: 100} |
- 作为对象方法被调用
1 | const zhangsan = { |
- 在 class 方法中被调用
1 | class People { |
- 箭头函数
1 | const zhangsan = { |
重点:
this 取什么值,是函数执行的时候确定的,而不是定义的时候
异步
知识点:
单线程和异步
JS 是单线程语言 只能同时做一件事
JS 和 DOM 渲染共用同一个线程 因为 JS 可修改 DOM 结构
异步是基于 JS 单线程语言的特性
异步是基于 callback 函数调用
异步不会阻塞代码
同步会阻塞代码
Promise 解决 callback hell
应用场景
网路请求,ajax 调用 加载图片
定时任务
setTimeout
微观任务与 宏观任务
微观任务先于宏观任务
微观任务有(js 引擎发起的任务):
promise
Object.observe
宏观任务有(宿主 浏览器/node 发起的任务):
setTimeout
setInterval
JS-Web-API-DOM
DOM (Document Object Model)
DOM 的本质:就是从 HTML 文件中解析出来的树
DOM 的节点操作
1 | <div id="div1" class="container"> |
1 | const div1 = document.getElementById('div1') // 元素 |
DOM 的结构操作
1 | <div id="div1" class="container"> |
1 | const div1 = document.getElementById('div1') |
DOM 的性能
DOM 操作比较 “昂贵” ,尽量避免频繁操作 DOM
提高 DOM 的性能有以下两种方式:
- 对 DOM 查询做缓存
1 | // 不缓存 DOM 查询结果 |
- 将频繁查询改为一次查询
1 | const list = document.getElementById('list') |
JS-Web-API-BOM
BOM (Browser Object Model)
知识点:
- navigator
1 | const ua = navigator.userAgent // 查看浏览器信息 |
- screen
1 | console.log(screen.width) |
- location
1 | console.log(location.href) //https://coding.imooc.com/lesson/115.html?a=100&b=200#mid=30378 |
- history
1 | history.back() // 后退 |
JS-Web-API-事件
事件绑定
1 | // 通用的事件绑定 |
事件冒泡
事件冒泡是基于 DOM 属性结构
事件会顺着触发元素向上冒泡
p
=>div
=>body
=>document
应用场景:事件代理
1 | <body> |
1 | // 通用的事件绑定 |
事件代理
代码简洁
减少浏览器内存占用
不要滥用
1 | function bindEvent(elem, type, selector, fn) { |
JS-Web-API-Ajax
XMLHttpRequest 状态码
xhr.readyState
0:(未初始化)还没调用 send() 方法
1:(载入)已经调用 send() 方法,正在发送请求
2:(载入完成)send()方法执行完成,已经接收到全部响应内容
3:(交互)正在解析响应内容
4:(完成)响应内容解析完成,可以在客户端调用
xhr.status
2xx:表示成功处理请求,例如 200
3xx:需要重定向,浏览器直接跳转,例如 301,302,304
4xx:客户端请求错误,例如 404,403
5xx:服务器端错误,例如 500
同源策略和跨域
同源策略:
ajax 请求时 浏览器要求网页和 server 必须同源
同源:协议 域名 端口 必须一致
加载图片 css js 可无视同源策略
1 | <img src="跨域的图片地址" /> |
跨域:
所有的跨域,都必须经过 server 端允许和配合
未经 server 端允许就实现跨域,说明浏览器有漏洞
JSONP:
<script>
可绕过跨域限制服务器可以拼接任意数据返回
<script>
可以获取跨域数据 只要服务端配合返回
JSONP 原理: 允许客户端传一个 callback
参数给服务端,服务端返回数据时会将 callback
参数作为函数名来包裹 JSON 数据,这样客户端就定义函数来接收返回的数据
CORS
- 服务器设置 http header
ajax 常用插件:
jquery
fetch
axios
存储
cookie
- 本身是用于与服务端通信的
- 被借用来做本地存储的
cookie 的缺点
- 存储限时 4kb
- 只能通过 document.cookie = ’…‘的方式增加
- 每调一次接口 都会带上 cookie 请求
HTML5 存储
localStorage: 永久存储 除非手动或者代码删除
sessionStorage: 仅存在当前会话中 浏览器关闭就会清空
开发环境
页面加载过程
性能优化
性能优化原则:
多使用内存 缓存或其他方法
减少 cpu 计算量 减少网络加载耗时
简单来说 就是空间换时间
让渲染更快:
css 文件放在 head 里 js 文件放在 body 之后
懒加载(上滑加载更多 图片懒加载)
尽早执行 js 使用 DOMContentLoaded 触发
题目:
3. window.onload 和 DOMContentLoaded 的区别
考点:页面加载过程
window.onload:等到页面全部加载完成后执行,包括图片、视频等媒体资源
DOMContentLoaded:等到 dom 节点渲染后就执行,不包括图片、视频等媒体资源
4. JS 创建 10 个 a 标签,点击的时候弹出对应的序号
考点:JS 作用域
1 | let a |
5. 手写节流 throttle 、防抖 debounce
考点:性能、体验优化
6. promise 解决了什么问题?
考点:JS 异步
20.手写一个简易的 ajax
21. 从输入 url 到渲染的页面整个过程
页面过程:
- DNS 解析:域名 => ip 地址
- 通过 ip 地址去向服务器发起 http 请求
- 服务器处理 http 请求 并返回数据给浏览器
渲染过程:
- 根据 html 代码 生成 DOM tree
- 根据 css 代码 生成 CSSOM
- 生成的 DOM 和 CSSOM 整合成 Render tree
- 根据 Render tree 开始渲染页面
- 渲染遇到
<script>
停止渲染 优先加载 JS 代码 完成后再继续 - 直到页面全部渲染完成