面试问题整理

210 阅读22分钟

面试问题整理

HTML 相关

行内元素/块级元素/空元素有哪些?

行内元素: a/img/span/b/strong/input/select/section

块级元素: div/p/table/ul/ol/li/h1-h6

空元素: br/hr/img/input/link/meta

HTML5新特性有哪些?如何处理HTML5新标签的兼容性问题?如何区分HTML和HTML5?

HTML5新特性:

绘图方面:加入了canvas绘图和SVG绘图;

媒体方面: 加入了video和audio标签

语义化标签: 比如header、nav、footer、section ['sekʃ(ə)n]、article ['ɑrtɪkl]

本地离线存储: localStorage[ˈloʊkl] 和sessionStory两种本地离线缓存 localStorage是长期储存数据,关闭浏览器后数据不会丢失 sessionStorage是关闭浏览器后数据自动删除

表单控件: calendar、date、time、email、url、search ;

以及一些新技术: webwoker / websocket (säkit)/ GelolCation(ˌjēōlōˈkāSHən)

如何区分HTML和HTML5: 通过Doctype声明/新增的结构元素/功能元素

HTML5离线缓存怎么使用,工作原理能不能解释一下?

用户在没有联网时,可以正常访问站点或应用,等用户联网时,更新用户的缓存文件 浏览器是怎么对HTML5进行离线缓存资源进行管理和加载的?:在联网情况下,html头部有manifest属性,会请求manifest文件,如果是第一次访问,浏览器会根据manifest的内容下载相应的资源并且进行离线缓存,如果不是第一个,会加载成为新的manifest文件,新旧manifest文件对比,如果一致,则不发生变化,如果不一致,那么会重新下载文件中的资源并进行离线缓存

Iframe有哪些缺点?

Iframe会阻碍页面的onload事件

浏览器的搜索引擎一般读无法解读iframe页面,不利于SEO的搜索

Iframe和主页面共享链接池,会影响页面的并行加载

使用js动态添加iframe src属性,可以避免一三问题

Label的作用是什么?怎么用?

label标签是定义表单控制间的关系,当用户点击label里面的文字时,浏览器会自动把光标转载表单控件上

HTML5的form如何关闭自动完成功能?

给不想要提示form或某个input设置autocomplete = off

页面可见性有哪些用途?(visibility API)

可以通过visibilityState检测当前页是否可见,以及打开网页的时间,可以 控制页面在被切换后,停止视频和音频的播放

Canvas和Svg有什么区别?

svg绘制出来的每一个图形的元素都是独立的DOM节点,能够方便的绑定事件或用来修改。canvas输出的是一副画布

svg输出的图形是矢量图形,后期可以修改参数来自由放大缩小,不会失真和锯齿。而canvas输出标量画布,就像一张图片一样,放大会失真或者锯齿

CSS 相关

☆清除浮动的方式

1. 在子元素并级后面添加一个新元素,添加clear:both属性

优点:通俗易懂,容易掌握

缺点:添加无意义空标签,不方便后期维护

2. 给父元素添加overflow:hidden

优点:代码较少,简单方便

缺点:不能配合定位使用

3. :after方法(作用于浮动元素的父元素)

优点:结构和语义化完全正确

缺点:复用方式不当,会造成代码量增加

.clearfix:after{
content:"";
visibility:hidden;
}
/* 为兼容IE6,IE7,因为ie6,ie7不能用after伪类 */
.clearfix{
zoom:1;
}

☆CSS3新特性和伪类有哪些?

新特性:

border-radius(圆角)/box-shadow(阴影)

text-shadow(文字阴影)/线性渐变(line-gradient)/transform各种样式(旋转/缩放/定位[xyz]/倾斜)

增加了更多的CSS旋转武器,背景颜色加入了rgba

Border-images/媒体查询/多栏布局

新增伪类:

P: first-of-type 选择属于其父元素中的同类型的第一个P元素

P:last-of-type 选择其父元素中的同类型的最后一个P元素

::after/::before在元素之前或之后添加内容

::disabled 控制表单控件的禁用状态

::checked 单选框或复选框被选中

如何居中div?

  1. 水平居中使用margin(0 auto),垂直居中:position:absolute;

  2. top:50%;Left:50%;transform:translate(-50%,-50%)

Display有哪些哪些值?说明他们的作用

block 元素转化为块级元素

inline 元素转化为行内元素

inline_block 元素转化问行内块元素

None 次元素不会显示,脱离文档流

List-item 元素转化为行内样式,并添加列表样式(如UL下的li)

Table 元素会以块级表格来显示

Inherit 继承父元素display属性

CSS实现单行文本移除显示...

overflow : hidden ;

text-overflow : ellipsis ;

white-space : nowrap ;

实现多行文本溢出显示...

display : -wedkit-box ;

-webkit-box-orient : vertical ;

-webkit-line-clamp : 3 ;

overflow : hidden ;

适用范围 : 因使用了Webkit的CSS扩展属性,该方法适用于Webkit浏览器以及移动端

注:-webkit-line-clamp用来限制在一个块元素显示的文本的行数,为了实现该效果,它需要组合其它的webkit属性。

常见结合属性:

display:-webkit-box; 必须结合的属性,将对象作为弹性伸缩盒子模式显示。

-webkit-box-orient 必须结合的属性,设置或减缩伸缩盒对象的子元素排列方式。

em,rem,px的区别?

px像素单位-----相对长度单位,相对于显示屏分辨率。

特点: IE无法调整那些使用px作为单位的字体大小

国外的大部分网站能够调整的原因在于其使用了em或rem作为字体单位

Firefox能够调整px和em、rem,但是96%以上的中国网民使用IE浏览器或(内核)

em-------相对长度单位,相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对于浏览器的默认字体尺寸(浏览器的默认字体大小是16px。未经调整的浏览器都符合1em = 16px)

特点: em的值不是固定的

em会继承父级元素的字体大小

rem-----rem是CSS3新增的一个相对访问(root em,根em),这个单位引起了广泛关注。rem与em的区别在于使用rem为元素设定字体大小时,仍然是相对大小,但相对的是HTML根元素。这个单位可以根据修改根元素就成比例的调整字体大小。可避免字体大小逐层复合的连锁反应。

JS相关

JS数据类型有哪些?

栈: (原始数据) string/number/boolean/null/undefined/symbol

堆: (引用数据类型)object(array和函数属于object)

数据类型一共7(6种基本类型+1种引用类型)种

栈与堆的区别?

栈与堆的储存位置不同;

原始数据是储存在栈中简单数据段,体积小,大小固定,属于频繁使用的数据.

引用数据类型是储存在堆中的对象,占据的空间大,如果储存在栈中会影响运行性能,引用数据类型在栈中指明了自己的所在地.当代码解析时,会先从栈中获取地址,然后再从堆中获取实体;

js中的作用域与变量声明提升

作用域:每一个变量、函数都有其作用的范围,超出范围不得使用,这个叫做作用域

全局变量、局部变量:

全局变量:在全局范围内声明的变量,如var a =1;

只有赋值没有声明的值,如a =1(注:如果a=2在函数环境中,也是全局变量)

局部变量:写入函数的变量,叫做局部变量,作用范围仅限函数内部

作用:程序安全,内存的释放

作用域链:

查找变量的过程。先找自己局部环境内部有没有声明或者是函数,如果有,则查看声明有无赋值或者是函数的内容,如果没有,则向上一级查找。

变量声明提升:

在预编译阶段,编译器会把所有定义的变量全部提升到最顶部,即,把变量声明的语句会自动放置在最顶部。

JS原型和原型链

原型:函数都要prototype(显示原型)属性,而prototype会自动初始化一个空对象,这个对象就是原型对象

原型对象中会有一个constructor属性,这个属性将指向了函数本身

实例化对象都有一个_proto_(隐式原型)属性,_proto_属性指向原型对象

原型链: 从实例对象往上找构造这个实例的相关对象,然后这个关联的对象再往上找,找到创造它的上一级的原型对象,以此类推,一直到object.prototype原型对象终止,原型链结束. 原型链中的原型对象中的内容,是会被不同的实例,所共有的

☆call和apply的区别和作用?

apply和call都是调用一个对象的一个方法,用另一个对象替换当前对象。

相同点:方法的含义是一样的,即方法功能是一样的。并且第一个参数的作用是一样的

不同点:call可以传入多个参数、apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入

存在意义:实现(多重)继承

继承的方法有哪些?

原型链继承、构造继承、实例继承、拷贝继承、组合继承、寄生组合继承

继承详情解释:

既然要实现继承,那么我们首先要有一个父类,代码如下:

function Animal(name){
//属性
this.name = name || 'Animal';
//实例方法
this.sleep = function(){
console.log(this.name + "正在睡觉!")
}
}
//原型方法
Animal.prototype.eat = function(food){
console.log(this.name + "正在吃" + food);
}

1. 原型链继承****

核心: 将父类的实例作为子类的原型

function Cat(){ }

Cat.prototype = new Animal();

Cat.prototype.name = "cat";

//Test Code

var cat = new Cat();

console.log(cat.name); //cat

console.log(cat.eat("fish")); //cat正在吃fish

console.log(cat.sleep()); //cat正在睡觉

console.log(cat instanceof Animal); //true

console.log(cat instanceof Cat); //true

特点:

1. 非常纯粹的继承关系,实例是子类的实例,也是父类的实例

2. 父类新增原型方法、原型属性,子类都能够访问到

3. 简单,易于实现

缺点:

1. 要想实现子类新增属性的方法,必须要在new Animal( )这样的语句之后执行,补鞥呢放在构造器中

2. 无法实现多继承

3. 来自原型对象的引用属性是所有实例共享的

4. 创建子类实例时, 无法向父类构造函数传参

2.构造函数

核心: 使用父类的构造函数来增强子类实例,等于是赋值父类的实例属性给子类(没用的原型)

unction Cat(name){

Animal.call(this);

this.name = name || "Tom"

}

//Test Code

var cat = new Cat();

console.log(cat.name); //Tom

console.log(cat.sleep()); //Tom正在睡觉

console.log(cat instanceof Animal); //false

console.log(cat instanceof Cat); //true

特点:

1. 解决了1中,子类实例共享父类引用属性的问题

2. 创建子类实例时,可以向父类传递参数

3. 可以实现多继承(call多个父类对象)

缺点:

1. 实例并不是父类的实例,只是子类的实例

2. 只能继承父类的实例属性与方法,不能继承原型属性、方法

3. 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能

3.实例继承*

核心: 为父类实例添加新特性,作为子类实例返回

function Cat(name){

var instance = new Animal();

instance.name = name || "Tom";

return instance;

}

//Test Code

var cat = new Cat();

console.log(cat.name); //Tom

console.log(cat.sleep()); //Tom正在睡觉!

console.log(cat instanceof Animal); //true

console.log(cat instanceof Cat); //false

特点:

1. 不限制调用方法,不管是new子类()还是子类(),返回的对象具有相同的效果

缺点:

1. 实例是父类的实例, 不是子类的实例

2. 不支持多继承

4.拷贝继承

//拷贝继承

function Cat(name){

var animal = new Animal();

for(var p in animal){

Cat.prototype[p] = animal[p];

}

Cat.prototype.name = name || "Tom"

}

//Test Code

var cat = new Cat();

console.log(cat.name); //Tom

console.log(cat.sleep()); //Tom正在睡觉!

console.log(cat instanceof Animal); //false

console.log(cat instanceof Cat); //true

特点:

1. 支持多继承

缺点:

1. 效率较低,内存占用高(因为要拷贝父类的属性)

2. 无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)

5.组合继承

核心: 通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用

function Cat(name){

Animal.call(this);

this.name = name || "Tom";

}

Cat.prototype = new Animal();

//组合继承也需要修复构造函数的指向问题

Cat.prototype.constructor = Cat;

//Test Code

var cat = new Cat();

console.log(cat.name); //Tom

console.log(cat.sleep()); //Tom正在睡觉!

console.log(cat instanceof Animal); //true

console.log(cat instanceof Cat); //true

特点:

1. 弥补了方法2的缺陷,可以继承实例属性、方法,也可以继承原型属性和方法

2. 既是子类的实例,也是父类的实例

3. 不存在引用属性共享的问题

4. 可传参

5. 函数可复用

缺点:

1. 调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)

6. 寄生组合继承

核心: 通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法、属性,避免了组合继承的缺点

//寄生组合继承

function Cat(name){

Animal.call(this);

this.name = name || "Tom"

}

(function(){

//创建一个没有实例方法的类

var Super = function(){};

Super.prototype = Animal.prototype;

//将实例作为子类的原型

Cat.prototype = new Super();

})();

//Test Code

var cat = new Cat();

console.log(cat.name); //Tom

console.log(cat.sleep()); //Tom正在睡觉!

console.log(cat instanceof Animal); //true

console.log(cat instanceof Cat); //true

//该实现没有修复constructoe

特点:

1. 堪称完美

缺点:

1. 实现较为复杂

☆什么是闭包?闭包有什么作用?

由于在js中,变量到的作用域属于函数作用域,在函数执行后作用域会被清除、内存也会随之被回收,但是由于闭包是建立在一个函数内部的子函数,由于其可访问上级作用域的原因,即使上级函数执行完,作用域也不会随之销毁,这时的子函数---也就是闭包,便拥有了访问上级作用域中的变量权限,即使上级函数执行完后,作用域内的值也不会被销毁。

闭包解决了什么:在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

由于闭包可以缓存上级作用域,那么就使得函数外部打破了“函数作用域”的束缚,可以访问函数内部的变量。以平时使用的Ajax成功回调为例,这里其实就是个闭包,由于上述的特性,回调就拥有了整个上级作用域的访问和操作能力,提高了几大的便利。开发者不用去写钩子函数来操作审计函数作用域内部的变量了。

闭包有哪些应用场景:

闭包随处可见,一个Ajax请求的成功回调,一个事件绑定的回调函数,一个setTimeout的延时回调,或者一个函数内部返回另一个匿名函数,这些都是闭包。简而言之,无论使用何种方式对函数类型的值进行传递,当函数在别处被调用时都有闭包的身影

闭包的缺陷:由于闭包打破了函数作用域的束缚,导致里面的数据无法清除销毁,当数据过大时会导致数据溢出

☆new操作符在创建实例的时候经历了哪几个阶段

new创建了一个对象,共经历了4个阶段:

1. 创建一个空对象

2. 设置原型链

3. 让实例化对象中的this指向对象,并执行函数体

4. 判断实例化对象的返回值类型

字符串常用原生方法。

splite():用于把一个字符串分割成字符串数组

search():用于减缩字符串中指定的子字符串,或检索与正则表达式相匹配的字符串

indexOf():可返回某个字符换字符串中首次出现的位置

substring():用于提取字符串中介于两个指定下标之间的字符

trim():移除字符串两边的空格

replace():替换字符

数组常用原生方法

indexOf:返回指定元素的位置,若元素不存在返回-1

slice:接受1-2个参数,参数对应的是要返回的是要返回项的起始位置和结束位置,若只有一个参数,该方法返回从参数指定位置到数组结尾的所有项,如果还有两个参数,则返回起始位置到结束位置项,但是不包括结束位置项,返回的结果是一个新数组。

push:向数组末位添加若干元素,返回添加元素后数组的长度

pop:删除数组末位最后一个元素,但会被删除元素

unshift:向数组头部添加若干元素,返回添加元素后的数组长度

shift:删除数组头部的第一个元素,返回被删除的元素

sort:对数组进行排序,返回排序后的数组

reverse:对数组中的数据进行反转,返回反转后的数组

concat:将两个数组合并,返回新数组(可以接受任意元素和数组,并进行拆分放入数组)

join:将数组中的每一个元素用指定的字符串拼接起来

解释一下线程和进程的区别?

进程: 是资源分配的基本单词,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配CPU时间,程序开始真正运行。

线程: 是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分配的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下九允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

线程和进程个子有什么区别和优劣势?

1. 进程是资源分配的最小单位,线程是程序执行的最小单位。

2. 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。

3. 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点

4. 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间

什么是伪数组,如何将伪数组转换为真数组?

伪数组:无法直接调用数组方法或期望length属性有什么特殊的行为,不具有push、pop等方法,但仍可以对真正数组遍历方法来遍历它们。典型的是函数的argument参数等

伪数组的三大特性:

1. 具有length属性

2. 按索引方式存储数据

3. 不具有数组的push,pop等方法

将伪数组转化为标准数组需要用到数组原型中的方法 slice

例如: Array.prototype.slice.call( 伪数组名称 );

如何阻止事件冒泡和默认事件?

cancelBunnle(IE)

return false;

event.preventDefault( );

event.stopPropagation( );

列举常用的ES6特性:

1. let、const

2. 箭头函数

3. 类的支持

4. 字符串模块

5. symbols

6. Promises

Vue相关

什么是MVVM?

MVVM分为Model、View、ViewModel三者。 Model 代表数据模型,数据和业务逻辑都在Model层中定义; View 代表UI视图,负责数据的展示; ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作; Model 和 View 并无直接关联,而是通过 ViewModel 来进行联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。 这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom。

mvvm和mvc的区别?它和其他框架(JQuery)的区别是什么?哪些场景适合?

mvc和mvvm其实区别不大。都是一种设计思想,主要mvc中controller演变成mvvm中的ViewModel。mvvm主要解决了mvc中大量的DOM操作使页面渲染性能降低,加载速度变慢,影响用户体验

区别:vue数据驱动,通过数据来显示视图层而不是节点操作

场景:数据操作比较多的场景,更加便捷

Vue的优点是什么?

1. 低耦合:视图View可以独立于Model变化和修改,一个ViewModel可以绑定到不同给的“view”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

2. 可重用性:你可以把一些视图逻辑放在ViewModel里面,让很多view重用这段视图逻辑

3. 独立开发:开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计

4. 可测试:界面素来是比较难测试的,而现在测试可以针对ViewModel来写

Vue组件之间的传值

-父组件与子组件传值

父组件通过标签上定义传值(:父组件名称=”子组件props的名称”)

子组件通过props的方式接受数据

-子组件向父组件传递数据

子组件通过$emit方法传递参数给父组件

Vue-cli中怎么使用自定义组件,又遇到过哪些问题吗?

1. 在components文件中创建组件.vue文件.是script中export default{}

2. 在调用的页面中使用import XXX from 路径

3. 在调用的组建components属性中注册组件,注意大小写(文档不接受-连字符,可以使用驼峰命名)

Vue如何实现按需加载配合webpack设置

webpack中提供了require ensure()来实现按需加载。以前引入路由是通过import这样的方式引入,现在改为 const定义的方式他引入。

不进行页面按需加载引入方式:import home from ‘../XXX’

进行页面按需加载的引入方式:const home = ‘../XXX’

v-show和v-if指令的共同点和不同点

v-show指令是通过修改元素的display的CSS属性让其显示或隐藏

v-if指令是直接销毁和重建DOM节点,达到让元素显示和隐藏的效果

如何让CSS只在当前组件中起作用

在当前文档中使用style标签,并添加scope属性

的作用是什么?

keep-alive标签包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染

scss是什么?在vue-cli中安装使用步骤?有几大特性?

scss是css的预编译。

使用步骤:

1. 先安装css-loader、node-loader、scss-loader等加载器模块

2. 在build目录找到webpack.base.config.js,在那个extends属性中加一个拓展scss

3. 在同一个文件,配置一个module属性

4. 在组件的style标签上添加lang属性,lang=“scss”

特性:

可以使用变量($变量名=值);

可以用混合器

可以嵌套

为什么使用key?

当有相同标签名的元素切换时,需要通过key特性设置唯一的值来标记已让vue区分它们,否则vue为了效率只会替换相同标签内部的内容。

为什么避免v-if和v-for用在一起?

当vue处理指令时,v-for比v-if具有更高的优先级,通过v-if移动到容器元素,不会再重复遍历列表中的每个值,取而代之的事,我们只检查它一次,且不会再v-if为否的时候运行v-for。

VNode是什么?虚拟DOM是什么?

Vue在羽绒棉上渲染的节点,及其子节点成为“虚拟节”,简写为“VNode”。“虚拟DOM”是由Vue组件树简历起来的整个VNode树的称呼

简单描述每个周期具体适合哪些场景

生命周期钩子的一些使用方法:

beforecreate:可以在这加个loading事件,在加载实例时触发

created:初始化完成时的时间写在这里,如在这结束loading事件,异步请求也适宜在这里调用

mounted:挂载元素,获取到DOM节点

updated:如果对数据统一处理,在这里写上相应函数

beforeDestroy:可以做一个确认停止事件的确认框

nextTick:更新数据后立即操作DOM

Vue-router的跳转原理:

vue-router实现单页面路由跳转,提供了三种方式: hash方式、history模式、abstract模式,根据mode参数来决定采用哪一种方式

● hash: 使用 URL hash 值来作路由。默认模式。 ● history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。 ● abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端

路由之间的跳转:

声明式(标签跳转):<router-view>,DOM节点中使用v-link进行跳转,或使用router-link标签

编程式(js跳转)

怎么定义vue-router的动态路由以及如何获取传过来的动态参数?

在router目录下的index.js文件中,对path属性加上/:id

使用router对象的params id

vue-router有哪几种导航钩子?以及它的参数?

三种,一是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。

第二种:组件内的钩子

第三种:单独路由独享组件

beforeRouteEnter、afterEnter、beforeRouterUpdate、beforeRouteLeave

参数:有to(去的那个路由)、from(离开的路由)、next(一定要用这个函数才能去到下一个路由,如果不用就拦截)最常用就这几种

Vuex:

Vuex是一个专门为vue.js应用设计的状态管理架构,统一管理和维护各个Vue组件的可变化状态(可以理解为Vue组件中的那些data)

Vuex的五大属性:

Vue有五个核心概念:state、getters、mutations、actions、modules

state => 基本数据

getters => 从基本数据派生的数据

mutations => 提交更改数据的方法,同步!

actions => 像一个装饰器,包裹mutations,使之可以异步

modules => 模块化Vuex