JS面试题(0~2年)
2020-04-17 09:55:43 4 举报
AI智能生成
前端javascript面试
作者其他创作
大纲/内容
1. 课程介绍
课程讲解的重要知识点
1. ES6 class<br>2. Promise<br>3. 模块化<br>4. 手写代码题目<br>5. webpack<br>6. babel
知识点介绍
基础知识
1. 原型原型链<br>2. 作用域 闭包<br>3. 异步 单线程
API
1. DOM BOM<br>2. Ajax 跨域<br>3. 事件 存储
开发环境
1. 版本管理<br>2. 调试 抓包<br>3. 打包构建
运行环境
1. 页面渲染<br>2. 性能优化<br>3. Web安全
课程安排
1. JS基础知识<br>2. JS Web API<br>3. 开发环境<br>4. 运行环境<br>5. 知识体系总结<br>6. 面试技巧
课程收获
1. 如何应对面试和面试题,学习JS常见面试题<br>2. 学会"题目->知识点->解题"的思路<br>3. 学会前端JS的知识点和知识体系
关于面试
1. 几层工程师:基础知识<br>2. 高级工程师:基础知识+项目经验<br>3. 架构师:解决方案能力
关于基础
1. 工程师的自我修养:基础知识<br>2. 扎实的基础能让你高效的学习新技术
几个面试题
1. typeos能判断哪些类型?<br>2. 何时使用===何时使用==<br>3. window.onload和DOMContentLoaded的区别?<br>4. JS创建10个<a>标签,点击的时候弹出对象的序号<br>5. 手写节流throttle、防抖debounce<br>6. Promise解决了什么问题?
思考
1. 拿到一个面试题,你第一时间看到的是什么?<br>2. 如何看待网上搜出来的永远做不完的题海?<br>3. 如何对待接下来遇到的面试题?
如何搞定所有面试题
1. 上一节思考问题的结论<br>2. 题目考察的知识点
1结论
1. 拿到一个面试题,你第一时间看到->考点<br>2. 如何看待做不完的题海->不变应万变(题可变,考点不变)<br>3. 如何对待接下来的题目->题目到知识点,再到题目
2.知识点
1. typeof能判断的类型?<br>考点:JS变量类型<br>2. 何时使用===何时使用==<br>考点:强制类型转换<br>3. window.onloaded和DOMContentLoaded区别<br>考点:页面加载过程<br>4. JS创建10个<a>标签,点击的时候弹出对象的序号<br>考点:JS作用域<br>5. 手写节流throttle、防抖debounce<br>考点:性能、体验优化<br>6. Promise解决了什么问题?<br>考点:异步<br>
前端知识体系
1. 什么是知识体系<br>2. 从哪些方面梳理<br>3. 知识体系目录
什么是知识体系
1. 高效学习三部曲:找准知识体系;刻意训练;及时反馈<br>2. 知识体系:结构化的知识范围<br>3. 涵盖所有知识点;结构化、有组织、易扩展
从哪些方面梳理
1. W3C标准<br>2. ECMA262标准(ES6)<br>3. 开发环境(版本管理 调试 工程化 打包上线。。)<br>4. 运行环境(浏览器时怎么加载的 性能跟优化 体验优化 安全。。)
知识体系
1. JS基础语法<br>2. JS-Web-API <br>3. 开发环境
2. JS基础-变量类型和计算
变量类型
1. 值类型 vs 引用类型<br>2. typeof运算符<br>3. 深拷贝
值类型vs引用类型
常见值类型
undefined<br>string<br>number<br>boolean<br>symbol
引用类型
object<br>array<br>null<br>function
typeof运算符
typeof能判断哪些类型:<br>1. 识别所有的值类型<br>2. 识别函数<br>3. 判断是否是引用类型(不可再细分)
判断值类型
判断函数
深拷贝
手写深拷贝注意事项
1. 注意判断值类型和引用类型<br>2. 注意判断是数组还是对象<br>3. 递归
代码示例
变量计算
类型转换
1. 字符串拼接<br>2. ==<br>3. if语句和逻辑运算
字符串拼接
有字符串时,+号表示字符串拼接
==
==会发生类型转换
除了==null之外,其他一律使用===
if语句和逻辑运算
1. truly变量:!!a===true的变量<br>2. falsely变量: !!a===false的变量
逻辑判断
小结
1. 值类型 vs 引用类型,堆栈模型,深拷贝<br>2. typeof运算符<br>3. 类型转换,truly和falsely变量
3. JS基础-原型和原型链
题目
1. 如何判断一个变量是不是数组<br>2. 手写一个简易的jQuery, 考虑插件和扩展性<br>3. class的原型本质,怎么理解?
知识点
1. class和继承<br>2. 类型判断 instanceof<br>3. 原型和原型链
class&继承
class
1. constructor<br>2. 属性<br>3. 方法
代码演示
new的时候,调用constructor,并给它传参
继承
1. extends<br>2. super<br>3. 扩展或者重写方法
代码演示
super(name)<br>调用父类constructor中对this的赋值操作
MDN文档_super
描述
在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。<br>super关键字也可以用来调用父对象上的函数。
语法
super([arguments]); <br>// 调用 父对象/父类 的构造函数<br><br>super.functionOnParent([arguments]); <br>// 调用 父对象/父类 上的方法
类型判断 instanceof
它顺着__proto__向上查找
原型&原型链
原型
示例的原型图
原型关系
1. 每个class都有显示原型prototype<br>2. 每个实例都有隐式原型__proto__<br>3. 实例的__proto__指向对应class的prototype
基于原型的执行规则
1. 获取属性和方法时,现在自身寻找<br>2. 如果找不到,则去__proto__中查找
显示原型 隐式原型
class实际上是函数,它是一个语法糖
__proto__隐式原型<br>prototype显示原型
原型链
示例的原型链图示
原型链图示
hasOwnProperty
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
面试题
1. 如何判断一个变量是不是数组<br> a instanceof Array
2. 手写一个简易的jQuery, 考虑插件和扩展性<br> 用class实现
代码演示
3. class的原型本质,怎么理解?<br> 原型链和原型链图示<br> 属性和方法的执行规则
4. JS基础-作用域和闭包
题目
1. this的不同应用场景,如何取值?<br>2. 手写bind函数<br>3. 实际开发中闭包的应用场景,举例说明
知识点
1. 作用域和自由变量<br>2. 闭包<br>3. this
作用域&自由变量
作用域
1. 全局作用域<br>2. 函数作用域<br>3. 块级作用域(ES6新增)
块级作用域
自由变量
1. 一个变量在当前作用域没有定义,但被使用了<br>2. 向上级作用域,一层一层依次寻找,直到找到为止<br>3. 如果到全局作用域都没找到,则报错 xx is notdefined
自由变量:在 A 中作用域要用到的变量 x,并没有在 A 中声明,要到别的作用域中找到他,这个变量 x 就是自由变量。
闭包
作用域应用的特殊情况,有两种表现:<br>1. 函数作为函数参数传递<br>2. 函数作为返回值被返回
函数作为返回值
函数作为参数被传递
所有的自由变量的查找,是在函数定义的地方,向上级作用域查找<br>不是在执行的地方!!!
this
1. 作为普通函数<br>2. 使用call apply bind<br>3. 作为对象方法被调用<br>4. 在class方法中调用<br>5. 箭头函数
bind返回一个新的函数,需要再调用这个函数
this是在函数执行的时候确定的,不是在定义的地方
题目解答
1. this的不同应用场景,如何取值?<br>
1. 当做普通函数被调用<br>2. 使用call apply bind<br>3. 作为对象方法调用<br>4. 在class的方法中调用<br>5. 箭头函数
2. 手写bind函数<br>
bind-demo.js
3. 实际开发中闭包的应用场景,举例说明
应用场景
1. 隐藏数据<br>2. 比如做一个简单的cache工具
cache ,隐藏数据,封装私有变量
模块块级作用域
模块块级作用域
小结
1. 作用域和自由变量<br>
2. 闭包:两种常见方式&自由变量查找规则<br>
自由变量的值在变量定义的时候确定
3. this<br>
this的值在函数执行时确定
1. 作为普通函数<br>2. 使用call apply bind<br>3. 作为对象方法被调用<br>4. 在class方法中调用<br>5. 箭头函数<br>
5. JS 基础-异步
题目
1. 同步和异步的区别是什么?<br>2. 手写Promise加载一张图片<br>3. 前端使用异步的场景有哪些?<br>4. setTimeout笔试题
知识点
1. 单线程和异步<br>2. 应用场景<br>3. callback hell 和 Promise
单线程和异步
异步出现的背景
1. JS是单线程语言,只能同时做一件事儿<br>2. 浏览器和nodejs已支持JS启动进程,如Web Worker<br>3. JS 和 DOM 渲染共用同一个线程,因为JS可修改DOM<br>4. 遇到等待(网络请求,定时任务)不能卡住<br>5.需要异步<br>6. 回调callback函数形式
异步解决的问题
1. 基于JS是单线程语言<br>2. 异步不会阻塞代码执行<br>3. 同步会阻塞代码执行
异步应用场景
1. 网络请求,如ajax图片加载<br>2. 定时任务,如setTimeout
ajax
图片加载
定时器
promise
回调地狱
使用promise
问题解答
1. 同步和异步的区别是什么?<br>
基于JS单线程<br> 异步不会阻塞代码执行<br> 同步会阻塞代码执行<br>
2. 手写Promise加载一张图片<br>
3. 前端使用异步的场景有哪些?<br>
1. 网络请求,如ajax图片加载<br>2. 定时任务,如setTimeout
4. setTimeout笔试题
答案,1 3 5 4 2
小结
1. 单线程和异步,异步和同步的区别<br>2. 前端异步的应用场景: 网络请求 & 定时任务<br>3. Promise解决callback hell
回顾
内容
1. 变量的类型和计算<br>2. 原型和原型链<br>3. 作用域和闭包<br>4. 异步和单线程
变量的类型和计算
题目
1. typeof能判断哪些类型<br>2. 何时使用==何时使用===<br>3. 值类型和引用类型的区别<br>4. 手写深拷贝
知识点
1. 值类型vs引用类型,堆栈模型,深拷贝<br>2. typeof运算符<br>3. 类型转换,truly 和falsly 变量<br>
原型和原型链
题目
1. 如何准确判断一个变量是不是数组<br>2. 手写一个简易的jQuery,考虑插件和扩展性<br>3. class的原型本质,怎么理解?
知识点
1. class和继承,结合手写jQuery的示例来理解<br>2. instanceof<br>3. 原型和原型链,图示&执行规则
作用域和闭包
题目
1. this的不同应用场景,如何取值<br>2. 手写bind函数<br>3. 实际开发中闭包的应用场景,距离说明|<br>4. 创建10个<a>标签,点击的时候弹出来对应的序号
知识点
1. 作用域和自由变量<br>2. 闭包:两种常见方式&自由变量查找规则<br>3. this
异步和单线程
题目
1. 同步和异步的区别是什么?<br>2. 手写用Promise加载一张图片<br>3. 前端使用异步的场景有哪些<br>4. setTimeout场景图
知识点
1. 单线程和异步,异步和同步区别<br>2. 前端异步的应用场景:网络请求&定时任务<br>3. Promise解决callback hell
JS Web API
从JS基础知识到JS Web API
1. JS 基础知识,规定语法(ECMA 262标准)<br>2. JS Web API , 网页操作的API(W3C标准)<br>3. 前者是后者的基础,两者结合才能真正实际应用
JS基础知识
1. 变量的类型和计算<br>2. 原型和原型链<br>3. 作用域和闭包<br>4. 异步
JS Web API 分哪几部分
1. DOM<br>2. BOM<br>3. 事件绑定<br>4. ajax<br>5. 存储
6. JS-Web-API-DOM
1. vue 和 React 框架应用广泛,封装了DOM操作<br>2. 但DOM操作一直都是前端工程师的基础、必备知识<br>3. 只会vue而不动DOM操作的前端程序员,不会长久
DOM
Document Object Model
题目
1. DOM是哪种数据结构<br>2. DOM操作常用的API<br>3. attr 和 property的区别<br>4. 一次性插入多个DOM节点,考虑性能
知识点
1. DOM本质(树)<br>2. DOM节点操作<br>3. DOM结构操作<br>4. DOM性能
节点操作
1. 获取DOM节点<br>
getElementById<br> getElementByTagName (集合)<br> getElementByClassName (集合)<br> querySelectorAll (集合)<br>
2. attribute<br>3. property
使用
区别
1. property: 修改对象属性,不会体现到html结构中<br>2. attribute: 修改html属性,会改变html结构(会直接修改标签中的属性)<br>3. 两者都有可能引起DOM重新渲染
结构操作
1. 新增/插入节点<br>2. 获取子元素列表,获取父元素<br>3. 删除子节点
代码演示
childNodes
DOM 性能
1. DOM操作非常'昂贵',避免频繁的DOM操作<br>2. 对DOM查询做缓存<br>3. 将频繁操作改为一次性操作
DOM查询做缓存
将频繁操作改为一次性操作
问题解答
1. DOM是哪种数据结构<br>
树(DOM树)
2. DOM操作的常用API<br>
1. DOM节点操作<br>2. DOM结构操作<br>3. 3. attr 和 property的操作
3. attr 和 property的区别<br>
1. property: 修改对象属性,不会体现到html结构中<br>2. attribute: 修改html属性,会改变html结构(会直接修改标签中的属性)<br>3. 两者都有可能引起DOM重新渲染
尽量使用property
4. 一次性插入多个DOM节点,考虑性能
小结
1. DOM本质<br>2. DOM节点操作<br>3. DOM结构操作<br>4. DOM性能(面试常考)
7. JS-Web-API-BOM
BOM
1. Browser Object Model
问题
1. 如何识别浏览器的类型<br>2. 分析拆解url各个部分<br>
知识点
1. navigator<br>2. screen<br>3. location<br>4. history
navigator screen
location
history.back()<br>history.forward()
8. JS-Web-API-事件
题目
1. 编写一个通用的事件监听函数<br>2. 描述事件冒泡的流程<br>3. 无限下拉的图片列表,如何监听每个图片的点击
知识点
1. 事件绑定<br>2. 事件冒泡<br>3. 事件代理
事件绑定
addEventListener
event.preventDefault() // 阻止默认行为
事件冒泡
event.stopPropagation() // 阻止冒泡
事件冒泡的流程
1. 基于DOM树形结构<br>2. 事件会顺着触发元素往上冒泡<br>3. 应用场景:代理
事件代理
1. 代码简洁<br>2. 减少浏览器内存占用<br>3. 但是,不要滥用
通用的事件监听函数
通用的事件监听函数
考虑bindEvent接收到3个参数还是4个参数
考虑代理<br>
考虑this, fn使用普通函数
问题解答
3. 无限下拉的图片列表,如何监听每个图片的点击
1. 事件代理<br>2. 用e.target获取触发元素<br>3. 用mathes来判断是否触发元素
小结
事件绑定<br>事件冒泡<br>事件代理
9. JS-Web-API-Ajax
题目
1. 手写一个简易的ajax<br>
2. 跨域的常用实现方式
知识点
1. XMLHttpRequest<br>2. 状态码<br>3. 跨域:同源策略,跨域解决方案<br>
XMLHttpRequest<br>
实现简易请求
xhr.onreadystatechange<br>和img.onload、img.onerror一样,都是回调函数
xhr.readyState
<span style="font-size: inherit;">0-(未初始化) 还没有调用send()方法</span><br style="font-size: inherit;"><span style="font-size: inherit;">1-(载入)已调用send()方法,正在发送请求<br></span>2-(载入完成)send()方法执行完成,已经接收到全部响应内容<br>3-(交互)正在解析响应内容<br>4-(完成)响应内容解析完成,可以在客户端调用<br>
xhr.status
2xx -表示成功处理请求,如200<br>3xx - 需要重定向,浏览器直接跳转,如301 302 304(301永久重定向,302临时重定向,304 资源未改变)<br>4xx - 客户端请求错误,如404 403(403无权限)<br>5xx - 服务端错误
同源策略和跨域
1. 什么是跨域(同源策略)<br>
1. ajax请求时,浏览器要求当前网页和server必须同源(安全) <br> 注意,是ajax请求,浏览器限制必须同源<br>2. 同源:协议、域名、端口 ,三者必须一致
加载图片 css js可无视同源策略
1. <img src=跨域的图片地址/>
<img />可用于统计打点,可使用第三方统计服务<br><br>
2. <link href=跨域的css地址><br>3. <script src=跨域的js地址></script><br> css js无视跨域策略,比如使用CDN地址时,就是跨域的
<link/><script>可使用CDN,CDN一般都是外域
注意
所有的跨域,都必须经过server端允许和配合<br>未经server端允许就实现跨域,说明浏览器有漏洞,危险信号
jsonp和cors
jsonp
1. 访问https://imooc.com/,服务端一定返回一个html文件吗?不一定<br>2. 服务器可以任意动态拼接数据返回,只要符合html格式要求<br>3. 同理于<script src=https://imooc.com/getData.js>,<br> 不一定返回js静态文件,可以返回符合js格式的任何内容
1. <script>可绕过跨域限制<br>2. 服务器可以任意动态拼接数据返回<br>3. 所以,<script>就可以获得跨域的数据,只要服务端愿意返回
可以用callback指定回调函数的名称<br>回调函数会定义成全局变量window.***<br>
url上的参数会自动的拼到回调函数的{}中
cors
问题解答
1. 手写一个简易的ajax<br>
2. 跨域的常用实现方式
Jsonp<br>cors
ajax常用插件
1. Jquery<br>2. fetch<br> fetch()返回的Promise不会被标记为reject,即使该HTTP响应的状态码是404或500<br> fetch()不会从服务端发送或者接收任何cookie,<br> 要发送cookie,必须设置credentials
3. axios<br> 支持Promise
get
传参
post
10. JS-Web-API-存储
题目
1. 描述 cookie localStorage sessionStorage区别<br>
知识点
1. cookie<br>2. localStorage 和 sessionStorage
cookie
1. 本身用于浏览器和server通讯<br>2. 被“借用”到本地存储来<br>3. 可用document.cookie=''来修改
缺点
1. 存储大小,最大4KB<br>2. http请求时需要发送到服务端,增加请求数据量<br>3. 只能用document.cookie=''来修改,太过简陋
localStorage和sessionStorage
1. HTML5专门为存储而设计,最大可存5M<br>2. API简单易用 setItem getItem<br>3. 不会随着http请求被发送出去
区别
1. localStorage数据会永久存储,除非代码或手动删除<br>2. sessionStorage数据只存在于当前会话,浏览器关闭则清空<br>3. 一般用localStorage会更多一些
问题解答
1. 描述 cookie localStorage sessionStorage区别
1. 容量<br>2. API易用性<br>3. 是否跟着http请求发送出去
11. 开发环境
关于开发环境
1. 面试官想通过开发环境了解候选人的实际工作情况<br>2. 开发环境的工具,能体现工作产出的效率<br>3. 会以聊天形式为主,不会问具体的问题<br>
1. git<br>2. 调试工具<br>3. 抓包<br>4. webpack babel<br>5. linux常用命令<br>
git
1. 最常用的代码版本管理工具<br>2. 大型项目需要多人协同开发,必须熟用git<br>3. 如果你不知道或者之前不用git,不会通过面试<br>4. Mac OS 自带git命令,windows可去官网下载安装<br>5. git服务端常见的有github coding.net等<br>6. 大公司会搭建自己的内网git服务
git常用命令
git add .<br>git commit -m "***"<br>git push origin master<br>git pull origin master<br>git branch<br>git checkout -b *** (创建新的分支并切换过去)<br>git checkout *** (切换分支)<br>git checkout . (撤销所有修改)<br>git merge ***<br>git status<br>git diff / git diff ***<br>git config user.name(配置用户名、邮件等)<br>git log<br>git show ***<br>git fetch (把服务端所有的分支都拉下来)<br>git stash (把修改暂存起来)<br>git stash pop (把暂存的修改释放出来)
添加SSH key
chrome调试工具
1. 一般不会面试时考察<br>2. 但这是前端工程师必备的技能
1. Elements<br>2. Console<br>3. debugger<br>4. Network<br>5. Application<br>6. Source
抓包
1. 移动端 h5页,查看网络请求,需要用工具抓包<br>2. windows 一般用fiddler<br>3. Mac OS 一般用charles
抓包过程
1. 手机和电脑连同一个局域网<br>2. 将手机代理到电脑上<br>3. 手机浏览网页,即可抓包
可以做什么?
1. 查看网络请求<br>
2. 网址代理<br> Tools-> Map Remote Settings<br>
把ajax.html代理到dom.html
https
有红❌号的,是https协议的请求,是加密协议,看不到
webpack&babel
为什么用webpack
1. ES6模块化,浏览器暂不支持<br>2. ES6语法,浏览器并不完全支持<br>3. 压缩代码,整合代码。以让网页加载更快
babel
作用
把ES6转换成ES5
安装插件
"@babel/core": "^7.6.2",<br> "@babel/preset-env": "^7.6.2",<br> "babel-loader": "^8.0.6",
配置
Module
webpack默认支持,不需要配置<br>
export
一起导出多个
分别导出多个
默认导出,导出一个
import
默认导出时,不能用解构赋值的方式导入
import obj from './c'<br>默认导出时,才能用这种方式导入
生产环境打包
mode: 'production',
filename: 'bundle.[contenthash].js',
linux
1. 公司的线上机器一般都是linux(参考阿里云)<br>2. 测试机也需要保持一致,用linux<br>3. 测试机或者线上机出了问题,本地又不能复现,需要去排查
常用命令
ssh work@192.168.10.21
进入linux线上机
ls -a
ls 平铺<br>-a all
ll
列表
clear
清屏
mkdir abc
创建文件夹abc
rm -rf abc
删除文件夹abc
- 表示参数<br>r表示递归<br>f表示强制
删除文件夹必须加上-rf
cd dist
进入dist目录
mv index1.html index.html
修改文件名,把index1.html修改为index.html
mv bundle.7477*** ../bundle.7477***
移动文件到上级目录
cd ../
进入上级目录
mv 是move的意思
cp a.js a1.js
cp 是 copy的意思
把a.js文件,拷贝到a1.js中
rm a1.js
删除a1.js文件<br>删除文件时可以不加 -rf<br>删除文件夹必须加上-rf,否则可能会出问题
touch d.js
新建文件d.js
vi d.js<br>或<br>vim d.js
进入vim编辑器模式,查看文件<br>如果有文件,直接打开<br>如果没有文件,先创建后打开
点击i
进入INSERT模式可以输入
点击esc
退出INSERT模式
:
等待输入
:w
written 写入保存
:q
quit 退出
:q!
强制退出
掌握编辑、保存、退出即可
cat package.json
打印出文件的所有内容
head package.json
打印出文件的头几行
tail package.json
打印出文件的最后几行
在文件中查找关键字
vimtutor
查看vim使用教程
总结
1. git <br>2. 调试工具<br>3. 抓包<br>4. webpack babel<br>5. linux常用命令
12. 运行环境
1. 运行环境即浏览器(server端有nodejs)<br>2. 下载网页代码,渲染出页面,期间会执行若干JS<br>3. 要保证代码在浏览器中,稳定且高效
1. 网页加载过程<br>2. 性能优化<br>3. 安全
网页加载过程
题目
1. 从输入url到渲染出页面的整个过程<br>2. window.onload和DOMContentLoaded区别
页面加载和渲染
1. 加载资源的形式<br>
1. html代码<br>2. 媒体文件,如图片、视频等<br>3. js css
2. 加载资源的过程<br>
1. DNS解析:域名->IP地址<br>2. 浏览器根据IP地址向服务器发起http请求<br>3. 服务器处理http请求,并返回给浏览器
3. 渲染页面的过程
1. 根据HTML代码生成DOM Tree<br>2. 根据CSS代码生成CSSOM(CSSOM是CSS Object Model)<br>3. 将DOM Tree和CSSOM整合形成 Render Tree<br>4. 根据Render Tree 渲染页面<br>5. 遇到<script>则暂停渲染,优先加载并执行JS代码,完成再继续<br> 优先加载并执行JS是因为,JS有可能改变当前渲染的结果<br>6. 直至把Render Tree渲染完成
示例
css 文件放到head中,可以一步渲染完成<br>如果不放到head中,可能会造成重复渲染
遇到js要暂停渲染,因为js可能会改变当前渲染的结果
js要放到body最后<br>如果js在中间,可能会导致页面渲染时间变长,因为js加载时会暂停渲染
img 标签不会阻塞DOM渲染<br>
问题解答
1. 从输入url到渲染出页面的整个过程
1. 下载资源:各个资源类型,下载过程<br>2. 渲染页面:结合html css js 图片等
2. window.onload和DOMContentLoaded区别
执行结果<br>dom content loaded<br>img loaded<br>window loaded
小结
1. 加载资源的形式<br>2. 加载资源的过程<br>3. 渲染页面的过程
性能优化
1. 是一个综合性问题,没有标注答案,但要求尽量全面<br>2. 某些细节问题可能会单独提问:手写防抖、节流<br>3. 只关注核心点,针对面试
原则
1. 多使用内存、缓存或者其他方法<br>2. 减少CPU计算量,减少网络加载耗时<br>3. (适用于多有编程的性能优化——空间换时间)
从何入手
1. 让加载更快<br>
减少资源体积:压缩代码<br>
减少访问次数<br>
合并代码<br>
比如模块化,多个模块打包成一个文件<br>图片合并,比如雪碧图<br>css代码合并
SSR服务器端渲染 <br>
缓存
使用更快的网络:CDN
2. 让渲染更快
1. CSS放到head里,JS放在body最下面<br>2. 尽早开始执行JS,用DOMContentLoaded触发<br>3. 懒加载(图片懒加载,上滑加载更多)<br>4. 对DOM查询进行缓存<br>5. 频繁DOM操作,合并到一起插入DOM结构中<br>6. 节流throttle 防抖debounce
示例讲解
资源合并
缓存
1. 静态资源加hash后缀,根据文件内容计算hash<br>2. 文件内容不变,则hash不变,则url不变<br>3. url和文件不变,则会自动触发http缓存机制,返回304
CDN
SSR
1. 服务端渲染:将网页和数据一起加载,一起渲染<br>2. 非SSR(前后端分离),先加载网页,再加载数据,再渲染数据<br>3. 早先的JSP ASP PHP,现在的 Vue React SSR,都是服务端渲染
懒加载
先加载预览图,等页面露出屏幕时,在把真实图片地址给src
缓存DOM查询
多个DOM一起插入DOM结构
尽早开始JS执行
两个工具函数<br>debounce<br>throttle
防抖 debounce
1. 监听一个输入框,文字变化后触发change事件<br>2. 直接用keyup事件,则会频繁触发change事件<br>3. 防抖:用户输入结束或暂停时,才会触发change事件
代码演示
debounce.js
节流 throttle
1. 拖拽一个元素时,要随时拿到该元素被拖拽的位置<br>2. 直接用drag事件,则会频繁触发,很容易导致卡顿<br>3. 节流: 无论拖拽速度多快,都会每隔100ms触发一次
代码演示
div1.addEventListener('drag', function(event) {<br><br>})
绑定事件时,监听到drag事件时,触发事件的回调函数,把事件对象event传给回调函数
div1.addEventListener('drag', throttle(function (e) {<br> console.log(e.offsetX, e.offsetY)<br>}))<br><br>
event会传给throttle返回的函数<br><br>arguments会拿到event<br>
target.addEventListener(type, listener, options);
type 表示监听事件类型的字符串。
listener<br>
当所监听的事件类型触发时,会接收到一个事件通知(实现了 Event 接口的对象)对象。listener 必须是一个实现了 EventListener 接口的对象,或者是一个函数。有关回调本身的详细信息,请参阅The event listener callback <br><br>描述了事件触发后执行的函数。<br>当事件触发时,事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件) 对象。<br>
安全
常见的web前端攻击方式有哪些?<br>
1. XSS跨站请求攻击
举例
1. 一个博客网站,我发表一篇博客,其中嵌入<script>脚本<br>2. 脚本内容:获取cookie,发送到我的服务器(服务器配合跨域)<br>3. 发布这篇博客,有人查看它,我轻松收割访问者cookie
XSS预防
1. 替换特殊字符,如< 变为&lt; >变为&gt;<br>2. <script>变为&lt;script&gt; ,直接显示,而不会作为脚本执行<br>3. 前端要替换,后端也要替换,都替换更保险
2. XSRF跨站请求伪造
举例
1. 我向你发送一封电子邮件,邮件标题很吸引人<br>2. 但邮件正文隐藏着<img src=xxx.com/pay?id=200 /><br> (img发送的请求是可以跨域的)<br>3. 你一插件邮件,就帮我购买了id是200的商品
预防
1. 使用post接口<br>2. 增加验证。例如密码、短信验证码、指纹等
不常发生
总结
1. 网页加载过程<br> 加载资源的形式<br> 加载资源的过程<br> 渲染页面的过程<br>2. 性能优化<br> 减少资源的体积:压缩代码<br> 减少访问次数:合并代码,SSR服务端渲染,缓存<br> 使用更快的网络:CDN<br> css放在head,JS 放在body最下面<br> 尽早开始执行JS,用DOMContentLoaded触发<br> 图片懒加载(图片懒加载,上滑加载更多)<br> 对DOM查询进行缓存<br> 频繁DOM操作,合并到一起插入DOM结构<br> 节流throttle 防抖debounce<br>3. 安全<br> XSS 跨站请求攻击和预防<br> XSRF跨站请求伪造和预防
13. 课程总结
问题
看思维导图
关于简历
1. 简洁明了,突出个人技能和项目经验,项目中使用的技术栈<br>2. 可以把个人博客、开源作品放在简历中(但博客要有内容)<br>3. 不要造假,保证能力上的真实性(斟酌用词,如精通***)
面试注意事项
1. 如何看待加班<br>2. 千万不要挑战面试官,反考面试官<br>3. 学会给面试官惊喜,证明你能想到更多,做的更好,但不要太多<br>4. 遇到不会的问题,说出知道的部分即可,但别岔开话题<br>5. 谈谈你的缺点:说一下你最近在学什么即可<br> 比如,小程序不熟,正在学习小程序(把缺点转化成学习态度积极)
14. 真题模拟(初级)
1. var let const的区别
1. var 是ES5语法,let const 是ES6语法<br>2. var 有变量提升<br>3. var 和 let 是变量,可修改;const是常量,不可修改<br>4. let const有块级作用域,var 没有
变量提升
块级作用域
2. typeof返回哪些类型
值类型:undefined string number boolean symbol<br>引用类型:object(注意,typeof null==='object')<br>function (function也有引用类型的特点)
3. 列举强制类型转换和隐式类型转换
1. 强制: parseInt parseFloat toString等<br>2. 隐式:if、逻辑运算、==、+ 拼接字符串
4. 手写深度比较,模拟loash的isEqual
5. split()和join的区别
6. 数组的pop push unshift shift分别做什么
1. 功能是什么<br>2. 返回值是什么<br>3. 是否会对原数组造成影响
会改变原数组的方法
pop<br>shift<br>push<br>unshift
pop
shift
shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
push
unshift
unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。
不改变原数组的方法
concat<br>map<br>filter<br>slice
concat
子主题
filter
slice
纯函数&非纯函数
什么是纯函数
1. 不改变源数组(没有副作用);<br>2. 返回一个数组
有哪些纯函数
concat<br>map<br>filter<br>slice
有哪些非纯函数
push pop shift unshift<br>forEach<br>some every<br>reduce
7. 数组slice 和 splice的区别
区别
功能区别(slice-切片,splice-剪接)
参数和返回值
是否是纯函数?<br>
slice是纯函数<br>splice不是纯函数
slice
slice
arr.slice()<br>拷贝arr
arr.sclice(-3)<br>最后3个
splice
splice
1 位置<br>2 长度<br>截掉位置1开始,长度为2的部分<br>把'a' 'b' 'c'进去填
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
8. [10,20,30].map(parseInt)返回结果是什么
要清楚<br>1. map的参数和返回值<br> 参数:函数<br> 返回值:数组<br>2. parseInt的参数和返回值<br><br>
parseInt
parseInt(string, radix) 将一个字符串 string 转换为 radix 进制的整数,<br> radix 为介于2-36之间的数。
parseInt(string, radix);
参数
string<br>要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用 ToString 抽象操作)。字符串开头的空白符将会被忽略。<br>radix 可选<br>从 2 到 36,代表该进位系统的数字。例如说指定 10 就等于指定十进位。请注意,通常预设值不是 10 进位!
返回值
返回解析后的整数值。 如果被解析参数的第一个字符无法被转化成数值类型,则返回 NaN。<br>注意:radix参数为n 将会把第一个参数看作是一个数的n进制表示,而返回的值则是十进制的。<br><br>例如:<br>parseInt('123', 5) // 将'123'看作5进制数,返回十进制数38 => 1*5^2 + 2*5^1 + 3*5^0 = 38<br>
9. ajax请求 get和post的区别?
1. get一般用于查询操作,post一般用户提交操作<br>2. get参数拼接在url上,post放在请求体内(数据体积可更大)<br>3. 安全性,post易于防止CSRF
10. 函数call 和 apply的区别
参数不同<br>fn.call(this,arg1,arg2,arg3), 序列<br>fn.apply(this,[arg1.arg2,arg3]) 数组
11. 事件代理(委托)是什么?
12. 闭包是什么,有什么特性,有什么负面影响
1. 回顾作用域和自由变量<br>2. 回顾闭包应用场景:作为参数被传入,作为返回值被返回<br>3. 回顾:自由变量的查找,要在函数定义的地方(而非执行的地方)
影响
1. 变量会常驻内存,得不到释放。闭包不要乱用<br> (不一定会造成内存泄露)
自由变量示例
闭包示例
返回函数
子主题
传入函数
13. 如何阻止事件冒泡和默认行为?<br>
event.stopProganation()<br>event.preventDefault()
14. 查找、添加、删除、移动DOM节点的方法?
查找DOM 修改DOM
代码演示
查找DOM-API
document.getElementById('idName')<br><br>//获取集合<br>document.getElementsByTagName('p')<br>document.getElementsByClassName('container')<br>document.querySelectorAll('p')
修改DOM
property
ele.style.width='100px'<br>ele.className = 'red'<br>
attribute
ele.setAttribute(key,val)<br>ele.getAttribute(key,val)
新建 插入 移动节点
代码演示
API
document.createElement('p')
新建节点
appendChild()
插入节点<br>or<br>移动节点(对现有节点进行appendChild会移动节点)
removeChild()
删除子元素
获取父元素 parentNode<br>获取子元素 childNodes
15. 如何减少DOM操作
1. 缓存DOM查询结果
比如for循环的判断条件中用到了DOM节点的length时,提前计算出来,不要再for循环中计算
2. 多次DOM操作,合并到一次插入<br>
16. 解释jsonp的原理,为何它不是真正的ajax
1. 浏览器的同源策略(服务端没有同源策略)和跨域<br>
2. 哪些html标签能绕过跨域?<br> <img /> <script>,因为他们要请求外域的资源,所以能绕过跨域 <br>
3. jsonp的原理
要实现跨域,必须有服务器端的支持
17. document load 和 ready的区别
load :全部资源加载完成,包括图片等<br>ready : DOM 渲染完成,此时图片等资源可能还没加载完
18. == 和===的不同
==会尝试类型转换<br>===严格相等<br>哪些场景才使用==(除了==null之外,其他一律使用===)
19. 函数声明和函数表达式的区别
函数声明
函数声明
函数表达式
用 var 声明
sum 提升了,是undefined<br>所以会提示 sum is not a function
用const声明
sum 不会提升<br>sum(10,20)的时候,sum还不存在
区别
函数声明 function fn(){ }<br>函数表达式 const fn=function(){ },必须先定义后使用<br>函数声明会在代码执行前预加载,而函数表达式不会
20. new Object() 和 Object.creat()区别
1. {} 等同于new Object(),原型是 Object.prototype<br>2. Object.create(null)没有原型<br>3. Object.create({....})可以指定原型
obj1===obj2 //false<br><br>
obj3 = new Object(obj1) <br>obj1 === obj3 // true
Object.create(null) 没有属性,也没有原型<br><br>new Object() 没有属性,但是有原型<br><br>
Object.create(proto[, propertiesObject])<br>创建一个空对象,把空对象的原型指向proto。<br>
obj6.__proto__===obj1 //true
21. 关于this的场景题
this的值是函数执行时确定的
22. 关于作用域和自由变量的场景题-1
23. 判断字符串以字母开头,后面字母数字下划线,长度6-30
示例
元字符
^ 开头<br>$ 结尾<br><br>* 匹配前面的子表达式零次或多次<br>+ 匹配前面的子表达式一次或多次<br>? 匹配前面的子表达式零次或一次<br><br><br>{n} 匹配确定的 n 次<br>{n,} 至少匹配n 次<br>{n,m} 最少匹配 n 次且最多匹配 m 次<br><br><br>x|y 匹配 x 或 y<br>[xyz] 字符集合。匹配所包含的任意一个字符<br>[a-z] 字符范围<br><br>\d 匹配一个数字字符。等价于 [0-9]。<br>\w 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。<br>
24. 关于作用域和自由变量的场景题-2
25. 手写字符串trim()方法,保证浏览器兼容性
26. 如何获取多个数字中的最大值<br>
27. 如何用JS实现继承
1. class继承<br>2. prototype继承
28. 如何捕获JS程序中的异常
1. 手动捕获try{} catch(err){}<br><br>2. 自动捕获 window.onerror
lineNum cloNum,截图中拼写错误
29. 什么是JSON
1. json是一种数据格式,本质是一段字符串<br>2. json格式和JS对象结构一致,对JS语言更友好<br>3. window.JSON是一个全局对象 JSON.stringfy JSON.parse
key必须用双引号引起来
30. 获取当前url参数<br>
两种方式
1. 传统方式,查找location.search<br>
2. 新API,URLSearchParams
示例
假设url为<br>https://processon.com/diagrams?b=20&a=10&c=30
location.search
const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i')<br><br>(^|&) 以开头符或者&开头<br><br>([^&]*) val部分不包含&号<br><br>(&|$) 以&或者结束符结尾<br>
URLSearchParams
31. 将url参数解析为JS对象<br>
32. 手写数组flattern,考虑多层级
使用API
Array.prototype.concat.apply([],arr)<br>相当于<br>Array.prototype.concat.call([],数组中所有的项)<br>
concat()
concat只能拍平一层嵌套
递归
33. 数组去重
1. 传统方式,遍历元素挨个比较、去重
、
forEach是遍历<br>indexof也要做遍历
2. 使用Set<br>[...new Set(arr)]<br>
[...new Set(arr)]
3. 考虑计算效率
Set的方式效率高<br>传统方式兼容性好
34. 手写深拷贝
手写深拷贝
Object.assign
Object.assign(target, ...sources)<br>Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象<br>
赋值对象到目标对象
不是深拷贝
35. 介绍一个RAF requestAnimationFrame
1. 要想动画流畅,更新频率要60帧/s,即16.67更细一次视图<br>2. setTimeout要手动控制频率,而RAF浏览器会自动控制<br>3. 后台标签或隐藏iframe中,RAF会暂停,而setTimeout依然执行
代码演示
36. 前端性能如何优化?一般从哪几个方面考虑
1. 原则:多使用内存、缓存,减少计算、减少网络请求<br>2. 方向:加载页面,页面渲染,页面操作流畅度
思维导图
JS基础知识
变量类型和计算
值类型和引用类型
类型判断
逻辑运算
原型和原型链
class
继承
原型
原型链
instanceof
作用域和闭包
作用域
自由变量
闭包
this
异步
单线程
callback
应用场景
Promise
模块化
ES6 Module
JS-Web-API
DOM
树形结构
节点操作
属性 attribute property
树结构操作
性能
BOM
navigator
screen
location
history
事件
绑定
冒泡
代理
ajax
XMLHttpRequest
状态码
跨域
存储
cookie
localStorage
sessionStorage
开发环境
git
调试
webpack 和 babel
linux命令
运行环境
页面加载
加载
渲染
性能优化
加载资源优化
渲染优化
安全
xss
CSRF
0 条评论
下一页