问题陈列

JS相关问题

  • JavaScript原型,原型链 ? 有什么特点?

    每个对象都会在其内部初始化一个属性,就是prototype(原型)。
    当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有自己的prototype,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

  • This对象的理解

    this总是指向函数的直接调用者;
    如果有new关键字,this指向new出来的那个对象;

this的指向问题:
1.作为对象的属性被调用,this指向该对象
2.作为普通函数得调用,this总是指向全局对象(通常为window),严格模式下this指向undefined
3.作为构造器调用,通常情况下this指向被构造函数返回的实例,例外如果构造函数显式的返回一个Object类型的对象,name结构也是只会得到这个对象
4.call和apply调用
动态改变this指向,使用一个指定的this值和单独给出的一个或多个参数来调用一个函数
允许为不同的对象分配和调用属于一个对象的函数/方法
call()方法:指定的this + 多个参数
apply()方法:指定的this + 一个包含多个参数的数组
5.箭头函数,箭头函数不会创建自己的this,它会从自己的作用域的上一层继承this

  • null,undefined 的区别?
    null 表示一个对象是“没有值”的值,也就是值为“空”;undefined 表示一个变量声明了没有初始化(赋值);
    undefined不是一个有效的JSON,而null是;
    undefined的类型(typeof)是undefined;null的类型(typeof)是object;
  • JS 深浅拷贝
    深拷贝和浅拷贝是只针对引用数据类型,例如:Object和Array;
    浅拷贝只复制指向某个对象的指针而不复制对象本身,新旧对象还是共享同一块内存;
    深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象;

深拷贝方法:
1.JSON.parse(JSON.stringify(obj))
原理: 用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝。
2.递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝

  • 闭包的概念
    闭包就是能够读取其他函数内部变量的函数,在本质上是函数内部和函数外部链接的桥梁
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 经典问题
var arr = []
for(var i = 0; i < 10; i++){
arr[i] = function () {
console.log(i)
}
}
arr[0](); // 10
arr[1](); // 10
arr[2](); // 10

// 利用闭包来解决
var arr = []
for(var i = 0; i < 10; i++){
arr[i] = (function (i) {
return function () {
console.log(i);
}
})(i)
}
arr[0](); // 0
arr[1](); // 1
arr[2](); // 2

闭包处理的还是作用域的问题,解决该问题的方法还可以是利用ES6语法,var声明改成let声明

浏览器相关问题

  • 前端页面有哪三层构成,分别是什么?作用是什么?
    分成:结构层、表示层、行为层

结构层:由 HTML 或 XHTML之类的标记语言负责创建。标签,也就是那些出现在尖括号里的单词,对网页内容的语义含义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。例如,P标签表达了这样一种语义:“这是一个文本段。”

表示层:由 CSS 负责创建。 CSS对“如何显示有关内容”的问题做出了回答。

行为层:负责回答“内容应该如何对事件做出反应”这一问题。这是 Javascript 语言和 DOM主宰的领域。

  • 你知道TCP协议、IP协议、HTTP协议分别在哪一层吗

    TCP协议在传输层,IP协议在网络层,HTTP协议在应用层。

  • 请说出三种减少网页加载时间的方法

1.服务器角度
采取CDN加速,开启gzip压缩,允许使用强缓存或协商缓存,增加服务器带宽

2.客户端角度
合理组织CSS、JavaScript代码位置,减少DOM操作、添加事件委托,部分操作可设置防抖和节流,对于可预见的操作采取preload或prerender的预加载,对于图片可以懒加载,合并CSS图片(精灵图/雪碧图),减少使用iframe,资源优化打包角度

3.资源优化打包角度
使用打包工具将Js文件、CSS文件和静态文件进行恰当打包处理。

  • 什么情况下会遇到跨域问题

跨域问题来自于浏览器的同源策略,即当协议、域名、端口号任意一个不同时,都会引发跨域问题。

解决方法:jsonp、CORS

  • 宏任务和微任务

宏任务是由宿主发起的(Node、浏览器),而微任务由JavaScript自身发起(JS引擎)。

宏任务(macrotask) 微任务(microtask)
发起者 Node、浏览器 JS引擎
具体事件 1. script (可以理解为外层同步代码)
2. setTimeout/setInterval
3. UI rendering/UI事件
4. postMessage,MessageChannel
5. setImmediate,I/O(Node.js)
1. Promise
2. MutaionObserver
3. Object.observe(已废弃;Proxy 对象替代)
4. process.nextTick(Node.js)
运行顺序 后运行 先运行
触发新一轮Tick 不会

其中比较注意的是promise的内部既包含宏任务也包含微任务,promise内部执行为宏任务,then执行为微任务

HTML相关问题

  • HTML新特性
1
2
3
4
5
6
7
8
9
10
11
12
1.语义标签
例如:<header>定义文档头部、<footer>定义文档尾部、<nav>定义文档的导航、<section>定义文档中的节

2.增强型表单
例如:<search>用于搜索、<tel>定义输入电话号码和字段、<date>选取日期

3.新增表单属性
例如:placehoder输入框默认提示文字、autofocus规定在页面加载时,域自动获得焦点、required要求输入的内容是否可为空

4.音频<audio src=" "></audio>、视频<video src=" "></video>

5.canvas绘图和SVG
  • webworker认识
    Web Worker的作用就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。

Worker线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。

  • src与href的区别
    href 是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。

src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。

CSS相关问题

  • CSS3有哪些新特性

border-radius:实现倒角、圆角
box-shadow:阴影
text-shadow:字体阴影
gradient:渐变
transform:rotate scale skew translate 旋转 缩放 定位 倾斜
animation:动画
等等

  • CSS选择器有哪些

1.id选择器 #id

2.类选择器 .class

3.标签选择器 div

4.相邻选择器 div+p

5.子选择器 div>p

6.后代选择器 div p

7.属性选择器 div[class=”main”]

8.伪类选择器 div::hover

  • CSS的盒子模型

有两种模型:IE盒子模型、标准盒子模型
IE盒子模型:content部分包含border和padding
标准盒子模型:内容(content)、填充(padding)、边界(margin)、边框(border)

在IE盒子模型中,width 和 height 指的是内容区域+border+padding的宽度和高度。
在标准盒子模型中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸

CSS3中的box-sizing属性:
box-sizing:border-box表示盒模型基于IE的盒模型,width和height决定盒模型的content区、padding区和border区。
box-sizing:content-box表示盒模型基于标准盒模型,width和height只决定盒模型的content区
box-sizing:inherit表示继承自父元素。

  • 元素水平垂直居中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*已知容器的宽高 设置层的外边距*/
div {
position: relative; /* 相对定位或绝对定位均可 */
width:500px;
height:300px;
top: 50%;
left: 50%;
margin: -150px 0 0 -250px; /* 外边距为自身宽高的一半 */
}

/*不知宽高-水平垂直居中 利用 `transform` 属性*/
div {
position: absolute; /* 相对定位或绝对定位均可 */
width:500px;
height:300px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

/*利用flex布局*/
div {
display: flex;
align-items: center; /* 垂直居中 */
justify-content: center; /* 水平居中 */
}

/*让绝对定位的div居中*/
div {
position: absolute;
width: 300px;
height: 300px;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
}

VUE相关问题

  • vue生命周期函数

beforeCreate( 创建前 ) => created(创建后)=> beforeMount(挂在前)=> mounted(挂载后)=>
beforeUpdate(数据更新前调用)=> updated(更新后)=> beforeDestroy(实例销毁前)=> destroyed(实例销毁后)
activated(被 keep-alive 缓存的组件激活时调用)
decactived(被 keep-alive 缓存的组件停用时调用)

  • vue响应式原理

实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调

  • vue父子组件的生命周期

1.加载过程
父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

2.子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated

3.父组件更新过程
父beforeUpdate->父updated

4.销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

vue组件间通信
①.props 和 $emit
父组间通过props向下传递数据给子组件,子组件通过event给父组件发送消息,实际上就是子组件把自己的数据发送给父组件。

②. $ attrs 和 $ listeners
祖孙间隔代通过$ attrs传递数据,$listeners监听数据的改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- A组件 -->
<template>
<div>
<B :messageb="messageb" :messagec="messagec" @getC="getC" @getB="getB" />
</div>
</template>

<script>
export default {
name: 'A',
data(){
return {
messageb:'b', //传递给B的数据
messagec:'c' //传递给C组件的数据
}
},
methods:{
//执行B子组件触发的事件
getB(val){
console.log('B组件的数据:'+ val) //打印 ‘B组件的数据:b’
},
//执行C子组件触发的事件
getC(val){
console.log("C组件的数据:" + val) //打印 'C组件的数据:c'
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!-- B组件 -->
<template>
<div>
<input type="text" v-model="mymessage" @change="chnageHandle()" />
<!-- C组件中能直接触发getC的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
<!-- 通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
<C v-bind="$attrs" v-on="$listeners" />
</div>
</template>

<script>
export default {
name: 'B',
props:[
messageb:{ // 获得A组件传递过来的数据:'b'
type: String,
default: ''
}
],
methods:{
chnageHandle(){
//触发A组件中的事件,把messageb给A组件
this.$emit('getB',this.messageb)
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- C组件 -->
<template>
<div>
<input type="text" v-model="$attrs.messagec" @change="changeHandle()">
</div>
</template>

<script>
export default {
name: 'C',
data () {
return {}
},
methods:{
changeHandle(){
//触发A组件中的事件,把从A得到的数据c还给A组件
this.$emit('getC',this.$attrs.messagec)
}
}
}
</script>

3.provide和 inject
provide 和 inject成对出现,用于父级组件向下传递数据;
父组件中通过provide来提供变量,然后在子组件中通过inject来注入变量。不论子组件有多深,只要调用了inject那么就可以注入provide中的数据。而不是局限于只能从当前父组件的prop属性来获取数据,只要在父组件的生命周期内,子组件都可以调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!-- 父组件 -->
<template>
<div>
<son></son>
</div>
</template>

<script>
export default {
name: 'grandparent',
provide: {
giveSonMessage:'给子组件的数据',
giveGrandsonMessage:'给孙组件的数据'
},
data(){
return {}
}
}
</script>

<!-- 子组件 -->
<template>
<div>
<input type="text" v-model="value">
<grandson></grandson>
</div>
</template>

<script>
export default {
name: 'son',
inject:['giveSonMessage'], //得到父组件传递过来的数据
data(){
return {
value:this.giveSonMessage
}
}
}
</script>

<!-- 孙组件 -->
<template>
<div>
<input type="text" v-model="value">
</div>
</template>

<script>
export default {
name: 'grandson',
inject:['giveGrandsonMessage','giveSonMessage'], //得到爷组件传递过来的数据,也能获得爷给父的数据
data(){
return {
value:this.giveGrandsonMessage
}
}
}
</script>

4.vuex处理组件之间的数据交互
如果业务逻辑复杂,很多组件之间需要同时处理一些公共的数据,这个时候才有上面这一些方法可能不利于项目的维护,vuex的做法就是将这一些公共的数据抽离出来,然后其他组件就可以对这个公共数据进行读写操作,这样达到了解耦的目的

TCP与IP的区别与联系

1.TCP工作于传输层,IP工作于网络层。

2.TCP提供应用进程之间的通信,而IP提供主机之间的通信。

3.TCP以IP为基础,面向应用层提供服务。IP协议为TCP提供服务。IP协议将数据从一台主机发送至另一台主机,TCP则保证了其传输可靠性。

4.TCP是面向连接的,而使用的低层网络可以是无连接的,也可以是连接的,但使用无连接的网络的会使整个网络系统更加灵活