1、从输⼊ URL 到⻚⾯加载完成,发⽣了什么?
简洁版:
-
浏览器根据请求的 URL 交给 DNS 域名解析,找到真实 IP ,向服务器发起请求;
-
服务器交给后台处理完成后返回数据,浏览器接收⽂件( HTML、JS、CSS 、图象等);
-
浏览器对加载到的资源( HTML、JS、CSS 等)进⾏语法解析,建⽴相应的内部数据结构 (如 HTML 的 DOM );
-
载⼊解析到的资源⽂件,渲染⻚⾯,完成。
详细版:
- ⾸先浏览器主进程接管,开了⼀个下载线程。
- 然后进⾏HTTP请求(DNS查询、IP寻址等等),中间会有三次捂⼿,等待响应,开始下载 响应报⽂。
- 将下载完的内容转交给Renderer进程管理。 Renderer进程开始解析css rule tree和dom tree,这两个过程是并⾏的,所以⼀般我会把 link标签放在⻚⾯顶部。
- 解析绘制过程中,当浏览器遇到link标签或者script、img等标签,浏览器会去下载这些内 容,遇到时候缓存的使⽤缓存,不适⽤缓存的重新下载资源。
- css rule tree和dom tree⽣成完了之后,开始合成render tree,这个时候浏览器会进⾏ layout,开始计算每⼀个节点的位置,然后进⾏绘制。
- 绘制结束后,关闭TCP连接,过程有四次挥⼿
2、html5有哪些新特性、移除了那些元素?
-
绘画 canvas
-
⽤于媒介回放的 video 和 audio 元素
-
本地离线存储 localStorage ⻓期存储数据,浏览器关闭后数据不丢失 sessionStorage 的数据在浏览器关闭后⾃动删除
-
语意化更好的内容元素,⽐如 article 、 footer 、 header 、 nav 、 section
-
表单控件, calendar 、 date 、 time 、 email 、 url 、 search
-
新的技术 webworker 、 websocket 、 Geolocation
3、请描述⼀下 cookies , session、sessionStorage 和 localStorage 的区别?
- cookie 是⽹站为了标示⽤户身份⽽储存在⽤户本地终端(Client Side)上的数据(通常 经过加密)
- cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递
- sessionStorage 和 localStorage 不会⾃动把数据发给服务器,仅在本地保存
存储⼤⼩:
- cookie 数据⼤⼩不能超过4k
- sessionStorage 和 localStorage 虽然也有存储⼤⼩的限制,但⽐ cookie ⼤得 多,可以达到5M或更⼤
有期时间:
- localStorage 存储持久数据,浏览器关闭后数据不丢失除⾮主动删除数据
- sessionStorage 数据在当前浏览器窗⼝关闭后⾃动删除
- cookie 设置的 cookie 过期时间之前⼀直有效,即使窗⼝或浏览器关闭
cookie详解:www.sohu.com/a/325419403…
token知识:www.cnblogs.com/xuxinstyle/… www.yyyweb.com/5144.html
-
1.sessionStorage:将数据保存在session对象中。所谓session,是指用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。session对象可以用来保存在这段时间内所要求保存的任何数据。
-
2.localStorage:将数据保存在客户端本地的硬件设备(通常指硬盘,也可以是其他硬件设备)中,即使浏览器被关闭了,该数据仍然存在,下次打开浏览器访问网站时仍然可以继续使用。 这两者的区别在于,sessionStorage为临时保存,而localStorage为永久保存。
Storage知识:www.cnblogs.com/pengc/p/871…
cookie和session的区别和联系:www.pianshen.com/article/157…
4、Canvas和SVG有什么区别?
-
svg 绘制出来的每⼀个图形的元素都是独⽴的 DOM 节点,能够⽅便的绑定事件或⽤来修 改。 canvas 输出的是⼀整幅画布
-
svg 输出的图形是⽮量图形,后期可以修改参数来⾃由放⼤缩⼩,不会失真和锯⻮。⽽ canvas 输出标量画布,就像⼀张图⽚⼀样,放⼤会失真或者锯⻮
canvas用法:www.runoob.com/html/html5-…
svg用法:www.runoob.com/svg/svg-tut…
5、浏览器的内核分别是什么?
- IE: trident 内核
- Firefox:gecko 内核
- Safari:webkit 内核
- Opera:以前是 presto 内核,Opera 现已改用 Google Chrome 的 Blink 内核
- Chrome:Blink
6、normalize.css
Normalize.css是一种CSS reset的替代方案。它在默认的HTML元素样式上提供了跨浏览器的高度一致性。 初始化css样式, vue中也可引入
7、Sass
看官网 主要要掌握混合器和继承的用法 @mixin 和@extend
8、BFC 块级格式化上下文
9、原型链
(一)www.jianshu.com/p/dee9f8b14…
(二)www.jianshu.com/p/652991a67…
(三)www.jianshu.com/p/a4e1e7b6f…
10、display:inline-block元素之间空隙的产生原因和解决办法
11、闭包
- 闭包就是能够读取其他函数内部变量的函数
- 闭包是指有权访问另⼀个函数作⽤域中变量的函数,创建闭包的最常⻅的⽅式就是在⼀个 函数内创建另⼀个函数,通过另⼀个函数访问这个函数的局部变量,利⽤闭包可以突破作⽤链域
- 闭包的特性: 函数内再嵌套函数 内部函数可以引⽤外层的参数和变量 参数和变量不会被垃圾回收机制回收
对闭包的理解
- 使⽤闭包主要是为了设计私有的⽅法和变量。闭包的优点是可以避免全局变量的污染,缺 点是闭包会常驻内存,会增⼤内存使⽤量,使⽤不当很容易造成内存泄露。在js中,函数即 闭包,只有函数才会产⽣作⽤域的概念
- 闭包 的最⼤⽤处有两个,⼀个是可以读取函数内部的变量,另⼀个就是让这些变量始终保 持在内存中
- 闭包的另⼀个⽤处,是封装对象的私有属性和私有⽅法
- 好处:能够实现封装和缓存等;
- 坏处:就是消耗内存、不正当使⽤会造成内存溢出的问题
另一种解释:
闭包就是那些引用了外部作用域中变量的函数。
为了更好的理解,我们将内部函数拆成闭包和纯函数两个方面:
1、闭包是那些引用了外部作用域中变量的函数。
2、纯函数是那些没有引用外部作用域中变量的函数,它们通常返回一个值并且没有副作用。
首先闭包可以引用函数外部变量,并且会沿着原型链向上寻找; 其次,闭包引用的变量在闭包存在时不会被回收,类似于,电脑里面一个文件夹中的文件被别的程序使用了就无法被删除到回收站,这时候需要把那个程序关掉,文件夹才能被删除,闭包也是这个道理
发现 JavaScript 中闭包的强大威力 juejin.cn/post/684490…
我从来不理解JavaScript闭包,直到有人这样向我解释它... zhuanlan.zhihu.com/p/56490498
破解前端面试(80% 应聘者不及格系列):从闭包说起 juejin.cn/post/684490…
12、js继承知识
一文吃透所有JS原型相关知识点: juejin.cn/post/684490…
13、Object.create()方法 常用于继承使用
Object.create()接收两个参数:
- 第一个参数是作为新对象的原型的对象
- 第二个参数是定义为新对象增加额外属性的对象(这个是可选属性)
- 如果没有传递第二个参数的话,就相当于直接运行object()方法
比如说我们现在要创建一个新对象B,那么要先传入第一个参数对象A,这个A将被作为B prototype;
var A = {
name:'A',
color:['red','green']
}
//使用Object.create方法先复制一个对象
var B = Object.create(A);
这时候我们console.log(B)
可以看到结果
所以它是可以直接把A对象作为了B的原型对象的
这是我们再看看第二个参数的用法
var A = {
name:'A',
color:['red','green']
}
//使用Object.create方法先复制一个对象
var B = Object.create(A, {
age: {
value: 24
}
});
这时候console.log(B)
14、new操作符具体干了什么呢?
1.当使用了构造函数,并且new 构造函数(),后台会隐式执行new Object()创建对象;
2.将构造函数的作用域给新对象,(即new Object()创建出的对象),而函数体内的this就代表new Object()出来的对象。
3.执行构造函数的代码。
4.返回新对象(后台直接返回);
15、如何进行跨域
- 九种跨域方式 juejin.cn/post/684490…
- cors跨域 www.ruanyifeng.com/blog/2016/0…
16、CMD、AMD、CommonJS的区别
17、为何需要同源策略或AJAX跨域访问被禁止的原因
18、Promise
es6.ruanyifeng.com/#docs/promi…
Promise.resolve()方法使用说明 blog.csdn.net/ixygj197875…
19、Object.assign()用法
20、es6中class类
21、什么是⾯向对象编程及⾯向过程编程,它们的异同和优缺点
- ⾯向过程就是分析出解决问题所需要的步骤,然后⽤函数把这些步骤⼀步⼀步实现,使⽤ 的时候⼀个⼀个依次调⽤就可以了
- ⾯向对象是把构成问题事务分解成各个对象,建⽴对象的⽬的不是为了完成⼀个步骤,⽽ 是为了描叙某个事物在整个解决问题的步骤中的⾏为
- ⾯向对象是以功能来划分问题,⽽不是步骤
⾯向对象编程思想
1、基本思想是使⽤对象,类,继承,封装等基本概念来进⾏程序设计
2、优点
- 易维护 :采⽤⾯向对象思想设计的结构,可读性⾼,由于继承的存在,即使改变需求,那么维 护也只是在局部模块,所以维护起来是⾮常⽅便和较低成本的
- 易扩展 开发⼯作的重⽤性、继承性⾼,降低重复⼯作量。
- 缩短了开发周期
22、如何通过JS判断⼀个数组
1、instanceof ⽅法
instanceof 运算符是⽤来测试⼀个对象是否在其原型链原型构造函数的属性
var arr = [];
arr instanceof Array; // true
2、constructor ⽅法
constructor 属性返回对创建此对象的数组函数的引⽤,就是返回对象相对应的构造 函数
var arr = [];
arr.constructor == Array; //true
3、Object.prototype.toString.call(value)
4、ES5 新增⽅法 isArray()
var a = new Array(123);
var b = new Date();
console.log(Array.isArray(a)); //true
console.log(Array.isArray(b)); //false
23、数组的排序
// 升序
var arr = [1,2,3,4,5,6,7,8,9,10]
arr.sort(function(a, b){
return a - b
})
//倒序
var arr = [1,2,3,4,5,6,7,8,9,10]
arr.sort(function(a, b){
return b - a
})
//乱序
var arr = [1,2,3,4,5,6,7,8,9,10]
arr.sort(function(){
return Math.random() - 0.5
})
24、怎样添加、移除、移动、复制、创建和查找节点
25、正则表达式
26、项⽬做过哪些性能优化?
- 减少 HTTP 请求数
- 减少 DNS 查询
- 使⽤ CDN
- 避免重定向
- 图⽚懒加载
- 减少 DOM 元素数量
- 减少 DOM 操作
- 使⽤外部 JavaScript 和 CSS
- 压缩 JavaScript 、 CSS 、字体、图⽚等
- 优化 CSS Sprite
- 使⽤ iconfont
- 字体裁剪
- 多域名分发划分内容到不同域名
- 尽量减少 iframe 使⽤
- 避免图⽚ src 为空
- 把样式表放在 link 中
- 把 JavaScript 放在⻚⾯底部
27、前端⾯试之MVVM浅析
blog.poetries.top/2018/10/20/…
28、实现⼀个函数clone
可以对 JavaScript 中的5种主要的数据类型,包括 Number 、 String 、 Object 、 Array 、 Boolean )进⾏值复
Object.prototype.clone = function(){
var o = this.constructor === Array ? [] : {};
for(var e in this){
o[e] = typeof this[e] === "object" ? this[e].clone() : th
}
return o;
}
29、VUE生命周期函数
30、vue-router知识
31、vuex State的使用
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
mapState 函数返回的是一个对象。我们如何将它与局部计算属性混合使用呢?通常,我们需要使用一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给 computed 属性。但是自从有了对象展开运算符,我们可以极大地简化写法:
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
32、vuex Getter的使用
getters的定义
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
mapGetters 辅助函数的使用
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
}
}
如果你想将一个 getter 属性另取一个名字,使用对象形式:
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
33、vuex Mutation的使用
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
}
34、vuex Action的使用
注册一个简单的 action
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
console.log(context)
context.commit('increment')
}
}
})
console.log(context)的内容为
mapActions函数的使用
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
35、vuex Module模块化管理
36、计算属性computed和侦听器watch
37、Vue 中 $nextTick 机制和异步async await的机制
juejin.cn/post/684490… juejin.cn/post/684490…
38、webpack多页应用打包 (有多个入口和多个html)
实现流程:
- 在
webpack.config.js中修改入口和出口配置
// 1. 修改为多入口
entry: {
main: './src/main.js',
other: './src/other.js'
},
output: {
path: path.join(__dirname, './dist/'),
// filename: 'bundle.js',
// 2. 多入口无法对应一个固定的出口, 所以修改filename为[name]变量
filename: '[name].js',
publicPath: '/'
},
plugins: [
// 3. 如果用了html插件,需要手动配置多入口对应的html文件,将指定其对应的输出文件
new HtmlWebpackPlugin({
template: './index.html',
filename: 'index.html',
chunks: ['main']
}),
new HtmlWebpackPlugin({
template: './index.html',
filename: 'other.html',
// chunks是指定要用到的入口文件,如不指定则会把所有入口文件都引入
// chunks: ['other', 'main']
chunks: ['other']
})
]
37、webpack的mode设置为prodction后做了什么?
-
tree shaking
tree shaking 是一个术语,通常用于打包时移除 JavaScript 中的未引用的代码(dead-code),它依赖于 ES6 模块系统中
import和export的静态结构特性。开发时引入一个模块后,如果只使用其中一个功能,上线打包时只会把用到的功能打包进bundle,其他没用到的功能都不会打包进来,可以实现最基础的优化
-
scope hoisting
scope hoisting的作用是将模块之间的关系进行结果推测, 可以让 Webpack 打包出来的代码文件更小、运行的更快
scope hoisting 的实现原理其实很简单:分析出模块之间的依赖关系,尽可能的把打散的模块合并到一个函数中去,但前提是不能造成代码冗余。 因此只有那些被引用了一次的模块才能被合并。
由于 scope hoisting 需要分析出模块之间的依赖关系,因此源码必须采用 ES6 模块化语句,不然它将无法生效。 原因和tree shaking一样。
let a = 1
let b = 2
let c = 3
console.log(a + b + c)
如上面的代码 打包完后代码后只会显示console.log(6) 而定义a b c的代码将会被清除掉,因为prodction模式会提前推测出结果
-
代码压缩
所有代码使用UglifyJsPlugin插件进行压缩、混淆
38、nvm的使用
39、Vue 内部是怎么知道 computed 依赖的?
40、Vue中mixins的使用方法
vue局部混入和全局混入Vue.mixin:www.cnblogs.com/bai-xue/p/1…
41、Vue.extend使用
blog.csdn.net/lixianghai2… www.cnblogs.com/hentai-miao…
42、VUE修饰符sync
43、Vue.js 父子组件通信的十种方式
vue中的listeners:www.cnblogs.com/dhui/p/1293…
44、Vue.nextTick 的原理和用途
45、Reflect的使用
es6.ruanyifeng.com/#docs/refle…
46、为什么要配环境变量?path用来干什么?
47、IP 协议、TCP 协议和 DNS 服务在使用 HTTP 协议的通信过程中各自发挥了哪些作用
48、代理、网关、隧 道
代理:
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户 端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时 也接收服务器返回的响应并转发给客户端。
网关:
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请 求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客 户端可能都不会察觉,自己的通信目标是一个网关。
隧道:
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方 通信连接的应用程序。