第一章 课程简介
拿到一个面试题,你第一时间看到的是什么? 考点
又如何看待网上搜出来的永远看不完的题海? 以不变应万变
如何对待接下来遇到的面试题? 题目到知识再到题目
第二章 JS基础知识(上)
变量类型
值类型VS引用类型
引用类型:对象、数组、函数
强制类型转换
字符串拼接
==
运算符
Eg:
100 == ‘100’// true
0 == ‘’// true
null == undefined //true
if语句
逻辑运算符
问题:JS中使用typeof
能得到的那些类型
typeof undefined // undefined
typeof ‘abc’ //string
typeof 123 //number
typeof true // boolean
typeof {} // object
typeof [] // object
typeof null // object
typeof console.log // function
问题:何时使用===
何时使用==
?
If(obj.a == null){
//这里相当于obj.a === null || obj.a == undefined ,简写形式
//这里是jquery源码中推荐的写法
}
问题:JS中有哪些内置函数 -数据封装对象
Object、Array、Boolean、Number、String、Function、Date、RegExp、Error
问题:JS变量按照存取方式区分哪些类型?
值类型 引用类型
问题:如何理解JSON
JSON只不过是JS对象而已
JSON.stringify({a:10,b:20})
JSON.parse('{"a":20,"10":20}')
原型和原型链
构造函数
构造函数 - 扩展
var a = {} - var a = new Object()
var a = [] - var a = new Array()
function Foo(){ ... } - var Foo = new Function( ... )
推荐使用前面的书写方式,不论从易读性和性能上看。
使用instance of
判断一个函数是否是一个变量的构造函数
判断一个变量是否为“数组”:变量instance of
原型规则和示例
1.所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了“null”之外)。
2.所有的引用类型(数组、对象、函数),都具有一个—proto(隐式原型)属性,属性值是一个普通的对象。
3.所有的函数,都有一个prototype(显示原型)属性,属性值是一个普通的对象。
4.所有的引用类型(数组、对象、函数),proto属性值指向它的构造函数的“prototype”属性值。
5.当试图得到一个对象的属性时,如果这个对象本身没有这个属性,那么会去它的的proto(即它的构造函数的prototype)中寻找。
循环对象自身的属性
原型链
Instance of
用于判断引用类型属于哪个构造函数的方法
解题
第三章 JS基础知识(中)
作用域和闭包
知识点
执行上下文
This
作用域
作用域链
闭包
执行上下文
范围:一段<script>或者一个函数
全局:变量定义、函数声明 一段<script>
函数:变量定义、函数声明、this、arguments 函数
PS:注意“函数声明”和“函数表达式”的区别
This
This要在执行时才能确认值,定义时无法确认
作为构造函数执行
作为对象属性执行
作为普通函数执行
Call apply bind
作用域
没有块级作用域
只有函数和全局作用域
作用域链
闭包
闭包的使用场景
函数作为返回值
函数作为参数传递
实际开发中闭包的应用
1.说下对变量提升的理解
变量定义
函数声明
- 说明this几种不同的使用场景
作为构造函数执行
作为对象属性执行
作为普通函数执行
Call apply bind
- 创建10个<a>便签,点击的时候弹出来对应的序号
var i;
for(i = 0;i < 10;i++){
(function(i){
a = document.createElement('a');
a.innerHTML = i + '<br>';
a.addEventListener('click',function(e){
e.preventDefault();
alert(i);
})
document.body.appendChild(a);
})(i);
}
- 如何理解作用域
自由变量
作用域链,即自由变量的查找
闭包的两个使用场景
第四章 JS基础知识(下)
异步和单线程
何时需要异步
在可能发生等待的情况
在等待过程中不能像alert一样阻塞程序进行
因此,所有的“等待的情况”都需要异步
前端使用异步的场景
定时任务:setTimeout,setInverval
网络请求:ajax请求,动态<img>加载
事件绑定
同步和异步的区别是什么
同步会阻塞代码执行,而异步不会
Alert是同步,setTimeout是异步
日期和math
日期
Math
数组API
对象API
日期
第五章 JS-Web-API(上)
回顾JS基础知识
变量类型和计算
原型和原型链
闭包和作用域
异步和单线程
其他(如日期、Math、各种常用API)
特点:表面看来并不能用于工作中开发代码
内置函数:Object Array Boolean String...
内置对象:Math JSON
我们连网页弹出一句hello world都不能实现
JS基础知识:ECMA 262标准
JS-Web-API:W3C标准
W3C标准中关于JS的规定有:
DOM操作
BOM操作
事件绑定
页面弹框window.alert(123),浏览器需要做:
定义一个window全局变量,对象类型
给它定义一个alert属性,属性值是个函数
获取元素document。getElementById(id),浏览器需要:
定义一个document全局变量,对象类型
给它定义一个getElementById的属性,属性值是个函数
但是W3C标准没有规定任何JS基础相关的东西
不管什么变量类型,原型,作用域和异步
只管定义用于浏览器JS操作页面的API和全局变量
全面考虑,JS内置的全局函数和对象有哪些?
总结
常说的JS(浏览器执行的JS)包括两部分:
JS基础知识(ECMA262标准)
JS-Web-API(W3C标准)
DOM操作
Document Object Model
DOM是哪种基本的数据结构?
DOM操作的常用API有哪些?
DOM节点的attr和property有何区别?
第六章 JS-Web-API(下)
//JS-Web-API
//通用事件绑定
var btn = document.getElementById('btn1');
btn.addEventListener('click',function(event){
console.log('clicked');
}
function bindEvent(elem,type,fn){
elem.addEventListener(type.fn)
}
var a = document.getElementById('link1');
bindEvent(a,'click',function(e){
e.preventDefault(); //阻止默认行为
alert('clicked');
})
//关于IE低版本的兼容性
//IE低版本使用attachEvent绑定事件,和W3C标准不一样
//IE低版本使用量已经非常少,很多网站都早已不支持
//建议对IE低版本的兼容性:了解即可,无需深究
//如果遇到对IE低版本要求苛刻的面试,果断放弃
//事件冒泡
// <div class="div1">
// <p id='p1'>激活</p>
// <p id='p2'>取消</p>
// <p id='p3'>取消</p>
// <p id='p4'>取消</p>
// </div>
// <div class="div2">
// <p id="p5">取消</p>
// <p id="p6">取消</p>
// </div>
var p1 = document.getElementById('p1');
var body = document.body;
bindEvent(p1,'click',function(e){
e.stopPropagation(); //阻止事件冒泡
alert('激活');
})
bindEvent(body,'click',function(e){
alert('取消');
})
//事件代理
// <div id="div1">
// <a href="#">a1</a>
// <a href="#">a2</a>
// <a href="#">a3</a>
// <a href="#">a4</a>
// </div>
var div1 = document.getElementById('div1');
div1.addEventListener('click',function(e){
var target = e.target;
if (target.nodename === 'A') {
alert(target.innerHTML);
}
})
//完善通用绑定事件的函数
function bindRvent(elem,type,selector.fn){
if(fn == null){
fn = selector;
selector = null;
}
elem.addEventListener(type,function(e){
var target;
if (selector) {
target = e.target;
if (target.matches(selector)) {
fn.call(target,e);
}else{
fn(e);
}
}
})
}
//使用代理
var div1 = document.getElementById('div1');
bindEvent(div1,"click","a",function(e){
console.log(this.innerHTML);
})
//不使用代理
var a = document.getElementById('a1');
bindEvent(div1,'click',function(e){
console.log(a.innerHTML);
})
代理的好处
1.代码简洁
2.减少浏览器内存占用
简述事件冒泡流程
1.DOM树形结构
2.事件冒泡
3.阻止冒泡
冒泡的应用
无限下拉加载图片的页面,绑定事件
使用代理
Ajax
XMLHttpRequest
状态码
跨域
readyState
0-(未初始化)还没有调用send()方法
1-(载入)已调用send()方法,正在发生请求
2-(载入完成)send()方法执行完成,已经接受全部响应内容
3-(交互)正在解析响应内容
4-(完成)响应内容解析完成,可以在客户端调用了
status
2xx-表示成功处理请求。如200
3xx-需要重定向,浏览器直接跳转
4xx-客户端请求错误,如404
5xx-服务端错误
跨域
JSONP
服务端设置http header
什么是跨域
浏览器有同源策略,不允许访问其他域接口
跨域条件:协议、域名、端口,有一个不同就算跨域
但是有三个便签允许跨域加载资源
<img src=xxx>
<link href=xxx>
<script src=xxx>
<img>用于打点统计,统计网站可能是其他域
<link><script>可以使用CDN,CDN的也是其他域
<script>可以用于JSONP
跨域注意事项
所有的跨域请求都必须经过信息提供方允许
如果未经允许即可获取,那是浏览器同源策略出现漏洞
JSONP实现原理
//加载http://coding.m.imooc.com/classindex.html
不一定服务器真正有一个classindex.html
服务器可以根据请求,动态生成一个文件,返回
同理于<script src="http://coding.m.imooc.com/api.js">
服务端设置http header
存储
请描述一下cookie,sessionStorage和localStorage的区别?
容量
是否会携带到ajax中
API易用性
cookie
本身用于客服端和服务端通信
但是它本身有本地存储的功能,于是就被“借用”
使用document.cookie=...获取和修改即可
cookie用于存储的缺点
存储量太小,只有4KB
所有的http请求都带着,会影响获取资源的效率
API简单,需要封装才能使用document.cookie=...
sessionStorage和localStorage
HTML5专门为存储而设计,最大容量5M
APi简单易用
localStorage.setItem(key.value);localStorage.getItem(key);
IOS safari隐藏模式下
localStorage.setItem会报错
建议统一使用try-catch封装
第七章 开发环境
关于开发环境
面试官想通过开发环境了解面试者的经验
开发环境,最能体现工作产出的效率
会以聊天的形式为主,而不是具体的问题
IDE(写代码的效率)
Git****(代码版本管理,多人协作开发)
JS模块化
打包工具
上线回滚的流程
IDE(集成开发环境)
Webstorm
Sublime
Vscode
Atom
插件 插件 插件!!!
如果你要走大牛、大咖、逼格的路线。就用Webstorm
如果你走普通、屌丝、低调路线,就用Sublime
如果你走小清新、个性路线,就用Vscode或者Atom
千万不要说你使用Dreamweaver或者Notpad++
不做.Net也不要用Visual Studio
不做Java也不要用Eclipse
Git
正式项目都需要代码版本管理
大型项目都需要多人协作开发
Git和Linux是一个作者
网络Git服务器如
coding.net
github.com
一般公司代码非开源,都有自己的Git服务器
搭建Git服务器无需了解太多
Git的基本操作必须很熟练
常用的Git命令
Git add
Git checkout xxx
Git commit -m “xxx”
Git push origin master
Git pull origin master
Git branch
Git checkout -b xxx/git checkout xxx
Git merge xxx
模块化
这本身就是一个面试的问题
知识点
不使用模块化的情况
使用模块化
AMD
CommonJS
不使用模块化
Util.js getFormatDate函数
A-util.js aGetFormatDate函数 使用getFormatDate
a. js aGetFormatDate
使用
代码中的函数必须是全局变量,才能暴露给使用方,但容易造成全局污染
依赖关系不清楚
使用模块化
AMD(异步模块定义)
Require.js requirejs.org/
全局define函数
全局require函数
依赖JS会自动、异步加载
CommonJS
nodejs模块化规范,现在被大量用于前端,原因:
前端开发依赖的插件和库,都可以从npm中获取
构建工具的高度自动化,使得使用npm的成本非常低
CommonJS不会异步加载JS,而是同步一次性加载出来
使用CommonJS
需要构建工具的支持
一般和npm一起使用
AMD和CommonJS的使用场景
需要异步加载JS,使用AMD
使用npm之后建议使用CommonJS
重点总结
AMD
CommonJS
两者的区别
Webpack
第八章 运行环境
运行环境
浏览器就可以通过访问链接得到页面的内容
通过绘制和渲染,显示出页面的最终的样子
整个过程中,我们需要考虑什么问题?
知识点
页面加载过程
性能优化
安全性
页面加载
加载资源的形式
加载一个资源的过程
浏览器渲染页面的过程
加载资源的形式
输入URL(或者跳转页面)加载html
<u>http://coding.m.imooc.com</u>
加载html中的静态资源
<script src=”/static/js/jquery.js”></script>
加载一个资源的过程
1.浏览器根据DNS服务器得到域名的IP地址
2.向这个IP的机器发送http请求
3.服务器收到、处理并返回http请求
4.浏览器得到返回内容
浏览器渲染页面的过程
1.根据HTML结构生成DOM Tree
2.根据CSS生成CSSOM
3.将DOM和CSSOM整合形成Render Tree
4.根据Render Tree开始渲染和展示
5.遇到<script>时,会执行并阻塞渲染
思考
为什么要把CSS放在head当中?
根据浏览器渲染过程,不放在head当中,损耗性能。
为什么要把JS放在body最下面?
不会阻塞body前面的标签渲染,加快渲染过程。
Window.onload和DOMContentLoaded
window.addEventListener('load',function(){
//页面的全部资源加载完才会执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded',function(){
//DOM渲染完成即可执行,此时图片、视频还可能没有加载完
})
Window.onload和DOMContentLoaded的区别
Window.onload:页面的全部资源加载完才会执行,包括图片、视频等
DOMContentLoaded:DOM渲染完成即可执行,此时图片、视频还可能没有加载完
性能优化
这本是就是一个综合的问题
原则
多使用内存、缓存或者其他方法
减少CPU计算、减少网络请求
从哪里入手
加载页面和静态资源
页面渲染
加载资源优化
1.静态资源的压缩合并
2.静态资源缓存
3.使用CDN让资源加载更快
4.使用SSR后端渲染,数据直接输入到HTML中
渲染优化
CSS放前面,JS放后面
懒加载(图片懒加载、下拉加载更多)
减少DOM查询,对DOM查询做缓存
减少DOM操作,多个操作尽量合并在一起执行
事件节流
尽早执行操作(如DOMContentLoaded)
资源合并
缓存
通过连接名称控制缓存
只有内容改变的时间,连接名称才会改变
CDN
使用SSR后端渲染
现在Vue React提出了这样的概念
其实jsp php asp 都属于后端渲染
懒加载
缓存DOM查询
//未缓存DOM查询
var i;
for (i = 0;i < document.getElementById('p').length;i++){
//todo
}
//缓存了DOM查询
var pList = document.getElementById('p');
var i;
for(i = 0;i < pList.length;i++){
//todo
}
合并DOM插入
var pList = document.getElementById('p');
var i;
for(i = 0;i < pList.length;i++){
//todo
}
//合并DOM插入
var listNode = document.getElementById('list');
//要插入10个li标签
var frag = document.createDocumentFragment();
var x,li;
for(x = 0;x < 10; x++){
li = document.createElement('li');
li.innerHTML = "List item" + x;
frag.appendChild(li);
}
listNode.appendChild(frag);
事件节流
var textarea = document.getElementById('text');
var timeoutId;
textarea.addEventListener('keyup',function(){
if (timeout) {
clearTimeout(timeId);
}
timeoutId = setTimeOut(function(){
//触发change事件
},100)
})
尽早操作
window.addEventListener('load',function(){
//页面的全部资源加载完才会执行,包括图片、视频等
})
document.addEventListener('DOMContentLoaded',function(){
//DOM渲染完成即可执行,此时图片、视频还可能没有加载完
})
安全性
综合性的问题:场景的前端安全问题有哪些?
XSS跨站请求攻击
XSRF跨站请求伪造
XSS
在新浪博客写一篇文章,同是偷偷插入一段<script>
攻击代码中,获取cookie,发送到自己的服务器
发布博客,有人查看博客内容
会把查看者的cookie发送到攻击者的服务器
XSRF
你已登录一个购物网站,正在浏览器商品
该网站付费接口是xxx.com/pay?id=100但是没有任何验证
然后你收到一封邮件,隐藏<img src=xxx.com/pay?id=100>
你查看邮件的时候,就已经悄悄的付费购买了
解决方案:
增加验证流程,如输入指纹、密码、短信验证码
面试技巧
简历
过程中...
简历
简洁明了,重点突出项目经历和解决方案
把个人博客放在简历中,并且定期维护更新博客
把个人的开源项目放在简历中,并维护开源项目
面试过程中
如何看待加班?加班就像借钱,救急不救穷
千万不可挑战面试官,不要反考面试官
学会给面试官惊喜,但不要太多
遇到不会回答的问题,说出你知道的也可以
谈谈你的缺点 - 说一下你最近正在学什么就可以了