1. HTML面试题
行内元素有哪些?块级元素有哪些? 空(void)元素有哪些?
行内元素:span img input
块级元素: div footer header section p h1...h6
空元素:br hr
元素之间的转换问题: display: inline; 把某元素转换成了行内元素 ===>不独占一行的,并且不能设置宽高 display: inline-block; 把某元素转换成了行内块元素 ===>不独占一行的,可以设置宽高 display: block; 把某元素转换成了块元素 ===>独占一行,并且可以设置宽高
页面导入样式时,使用link和@import有什么区别?
区别一:(兼容性)link先有,@import后有
区别二:加载顺序区别,先加载link 后加载@import
title与h1的区别、b与strong的区别、i与em的区别?
title与h1的区别:
定义: title:概括了网站信息,可以告诉搜索引擎或者用户关于这个网站的内容主题是什么 h1:文章主题内容,告诉蜘蛛我们的网站内容最主要是什么 区别: title他是显示在网页标题上、h1是显示在网页内容上 title比h1添加的重要 (title > h1 ) ==》对于seo的了解 场景: 网站的logo都是用h1标签包裹的
b与strong的区别:
定义: b:实体标签,用来给文字加粗的。 strong:逻辑标签,用来加强字符语气的。 区别: b标签只有加粗的样式,没有实际含义。 strong表示标签内字符比较重要,用以强调的。 题外话:为了符合css3的规范,b尽量少用该用strong就行了。
i与em的区别:
定义: i:实体标签,用来做文字倾斜的。 em:是逻辑标签,用来强调文字内容的 区别: i只是一个倾斜标签,没有实际含义。 em表示标签内字符重要,用以强调的。 场景: i更多的用在字体图标,em术语上(医药,生物)。
img标签的title和alt有什么区别?
区别一
title是鼠标放到图片上的提示
alt是图片没加载出来的默认显示东西
区别二
在seo层面上,要加入alt属性来描述这张图是什么内容或者关键字
png、jpg、gif 这些图片格式解释一下,分别什么时候用?
png: 无损压缩,尺寸比jpg大,适合做小图标
jpg: 采用压缩算法,有点失真,比png体积小,适合做中大图片
gif: 一般是动图
webp: 同时支持有损或者无损压缩,webp体积小,兼容性不好
如何关闭iOS键盘首字母自动大写
加一个属性autocapitalize='off' 即可
<input type="text" autocapitalize='off'>
怎么让Chrome支持小于12px 的文字?
chrome默认字体是16px
解决方法: 采用CSS3里的缩放transform:scale
<style type="text/css">
div{
font-size:10px;
}
div span{
display: inline-block;
-webkit-transform:scale(1.6);
}
</style>
ios系统中元素被触摸时产生的半透明灰色遮罩怎么去掉
设置tap-highlight-color: rgba(0,0,0,0)
<style>
a,button,input,textarea{
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
</style>
webkit表单输入框placeholder的颜色值能改变吗?
<style type="text/css">
input::-webkit-input-placeholder{
color:red;
}
</style>
禁止ios 长按时触发系统的菜单,禁止ios&android长按时下载图片
touch-callout: none
user-select:none
禁止ios 长按时触发系统的菜单,禁止ios&android长按时下载图片
html,body{
touch-callout: none;
-webkit-touch-callout: none;
user-select:none;
-webkit-user-select:none;
}
禁止ios和android用户选中文字
html,body{
user-select:none;
-webkit-user-select:none;
}
HTML5语义化
- 易读性和维护性更好。
- seo成分会更好,蜘蛛抓取更好。
- IE8不兼容HTML5标签的。解决:可以通过html5shiv.js去处理。
meta viewport 是做什么用的,怎么写?
HTML 5 有哪些标签?
H5 是什么?
Canvas和Svg区别是什么
2. CSS面试题
介绍一下CSS的盒子模型
css盒子模型有两种: 标准盒模型 和 IE盒子模型
标准盒子模型 (四个部分): margin + border + padding + content
IE盒子模型(两个部分): margin + content( border + padding + content )
通过css转换盒子模型
box-sizing:content-box 标准盒子模型
box-sizing:border-box IE盒子模型
line-height和height区别(大厂)
区别就是盒子高度
line-height 强调的是每一行文字的高,如果文字换行,整个盒子高度会增大(行数*行高)
height 是一个死值,就是这个盒子的高度
CSS选择符有哪些?哪些属性可以继承?
列举几个就行
CSS选择符:
通配符(*)
id选择器(#)
类选择器(.)
相邻选择器 (+) //选择下一个兄弟
后代选择器 (ul li)
子元素选择器(>)
CSS属性哪些可以继承
文字系列:font-size,color,line-height,text-align....
CSS属性哪些不可以继承
border,padding,margin.....
CSS优先级如何计算?
优先级: !important > 内联样式 > id > class > 标签 > 通配
CSS权重计算:(权重值)
内联样式 1000
id选择器 100
类选择器 10
标签&伪类选择器 1
通配符(> < + ...) 0
用CSS画一个三角形
用边框(border)画
盒子宽高设为0,先把全部边框设置为透明,三角形在哪就给哪个边框颜色,尺寸就可以了
一个盒子不给宽度和高度如何水平垂直居中?
最简单方法:弹性盒子
display:flex;
justify-content: center;
align-items: center;
第二种相对定位:
display有哪些值?说明他们的作用。
display值:
none 隐藏元素 block 把某某元素转换成块元素 inline 把某某元素转换成内联元素 inline-block 把某某元素转换成行内块元素
对BFC规范(块级格式化上下文:block formatting context)的理解?
BFC就是页面上隔离的独立容器.容器子元素不会影响到外面元素
了解BFC : 块级格式化上下文。
BFC的原则:如果一个元素具有BFC,那么内部元素再怎么弄,都不会影响到外面的元素。
如何触发BFC: float的值非none overflow的值非visible display的值为:inline-block、table-cell... position的值为:absoute、fixed
清除浮动有哪些方式?
-
overflow:hidden(触发bfc)
-
多添加一个盒子,盒子样式clear:both
-
after方式
ul:after{ content: ''; display: block; clear: both;}
在网页中的应该使用奇数还是偶数的字体?为什么呢?
偶数 : 让文字在浏览器上表现更好看。
另外说明:ui给前端一般设计图都是偶数的,这样不管是布局也好,转换px也好,方便一点。
有几种定位?分别是根据什么定位的?
position有哪些值?有什么作用?
static [默认] 没有定位
fixed 固定定位,相对于窗口定位
relative 相对定位,相对于自身定位,不脱离文档流(占位置)
absolute 相对于第一个有relative 父元素定位,脱离文档流(会飘起来,不占位置)
relative和absolute区别
- relative不脱离文档流 、absolute脱离文档流
- relative相对于自身 、 absolute相对于第一个有relative的父元素
- relative如果写了left、right、top、bottom ==》只有left、top absolute如果有left、right、top、bottom ==》left、right、top、bottom
写一个左中右布局占满屏幕,其中左、右俩块固定宽200,中间自适应宽,要求先加载中间块,请写出结构及样式。
双飞翼布局,通过margin-left:-100%,-200%控制左右两块
什么是CSS reset?
reset.css 就是用来重置css样式(冗余大,性能差)
normalize.css 为了增强跨浏览器渲染的一致性,一个CSS 重置样式库。(性能更好)
css sprite是什么,有什么优缺点
sprite就是精灵图/雪碧图
1.sprite是什么
就是把多个小图标合并成一个大图标
2.sprite优缺点
优点:减少http请求次数,提升性能
缺点:维护性比较差(一个小图标修改,大图标就要改)
display: none;与visibility: hidden;的区别
- 占用位置的区别 display: none; 是不占用位置的 visibility: hidden; 虽然隐藏了,但是占用位置(visibility:可视性看不见)
- 重绘和回流的问题(可以不说)
visibility: hidden; 、 display: none; 产生重绘 display: none; 还会产生一次回流
产生回流一定会造成重绘,但是重绘不一定会造成回流。
产生回流的情况:改变元素的位置(left、top...)、显示隐藏元素.... 产生重绘的情况:样式改变、换皮肤
opacity 和 rgba区别
共同性:都可以实现透明效果
opacity 取值范围0到1之间,0表示完全透明,1表示不透明
rgba R表示红色,G表示绿色,B表示蓝色,取值可以在正整数或者百分数。A表示透明度取值0到1之间
区别:继承的区别
opacity会继承,RGBA不会继承
opacity会继承父元素的opacity属性,而RGBA设置的元素的后代元素不会继承不透明属性。
::before 和 :after中双冒号和单冒号 有什么区别?解释一下这2个伪元素的作用。(缺)
-
区别 :是伪类、::伪元素 ===》是为了做区分
2.是什么?作用 元素before之前 、 元素after之后 作用:清除浮动、样式布局上也有作用
rem和em区别
相对于font-size
em是根据父元素的font-size rem是根据根(html)元素的font-size
rem是统一的参考标准(html元素),因此用的比较方便
自适应
自适应就是自适应屏幕尺寸
淘宝无限适配【移动端】:淘宝无限适配 + 布局单位使用rem
响应式
1. 是什么?
一个URL可以响应多端
2. 语法结构
@media only screen and (max-width: 1000px){ //@media 设置响应式条件
ul li:last-child{
display: none;
}
}
only : 可以排除不支持媒体查询的浏览器
screen : 设备类型
max-width | max-height
min-width | min-height
3. 响应式图片【性能优化】
<picture> //H5新增标签picture
<source srcset="1.jpg" media='(min-width:1000px)'> //media响应式图片
<source srcset="2.jpg" media='(min-width:700px)'>
<img srcset="3.jpg">
</picture>
布局方案
一、什么情况下采用响应式布局
数据不是特别多,用户量不是特别大,纯展示类的项目适合响应式布局
例如:公司的官网、专题页面
特别追求性能的项目,不太适合响应式,因为如果添加了很多的响应式就会造成加载速度变慢。
二、pc + 移动端应该做什么样的布局方案 注意:访问量还可以或者比较大,类似于淘宝网。
pc是一套,会加入一点点响应式。
移动端是一套,会使用自适应的布局方式。
三、pc的设计图
ui:1980
笔记本电脑:1280
ui图的宽度和电脑的宽度不对应该怎么办?
1. 把ui图进行等比缩放,缩放成和电脑一样的尺寸
2. 换1980的电脑
四、移动端的设计图
宽度:750
因为750设计图/2就是375,正好是iphone6的尺寸,我们要把iphone6的尺寸做为基准点。
必考:如何垂直居中?
必考:flex 怎么用,常用属性有哪些?
flex布局怎么把元素搞到页面四角处
3. JavaScript+ES6面试题
面试题:延迟加载JS有哪些方式?
延迟加载: async deffer
defer : 等html全部解析完成,才会执行js代码,顺次执行js脚本。 async : async是和html解析同步的(一起的),不是顺次执行js脚本(谁先加载完谁先执行)。
JS数据类型有哪些?
基本类型:string number boolean undefined null
引用类型:object
JS数据类型考题
字符串很厉害,和任何东西相加,都变成字符串
NAN 是一个数值类型,但是值不确定
console.log( true + 1 ); //2
console.log( 'name'+true ); //nametrue
console.log( undefined + 1 ); //NaN(是一个数值类型)
console.log( typeof undefined ); //undefined
console.log( typeof(NaN) ); //number
console.log( typeof(null) ); //object
null和undefined的区别
- 作者在设计js的都是先设计的null(为什么设计了null:最初设计js的时候借鉴了java的语言)
- null会被隐式转换成0,很不容易发现错误。
- 先有null后有undefined,出来undefined是为了填补之前的坑。
具体区别:JavaScript的最初版本是这样区分的:
null是一个表示"无"的对象(空对象指针),转为数值时为0;
undefined是一个表示"无"的原始值,转为数值时为NaN。
==和===有什么不同
== 比较的是值 ==是通过valueOf隐式转换后比较的
string == number || boolean || number ....都会隐式转换
通过valueOf转换(valueOf() 方法通常由 JavaScript 在后台自动调用,并不显式地出现在代码中。)
=== 除了比较值,还要比较类型
JS微任务和宏任务
- js是单线程的语言。
- js代码执行流程:同步执行完==》事件循环 同步的任务都执行完了,才会执行事件循环的内容 进入事件循环:请求、定时器、事件....
- 事件循环中包含:【微任务、宏任务】 微任务:promise.then 宏任务:setTimeout..
要执行宏任务的前提是清空了所有的微任务
流程:同步==》事件循环【微任务和宏任务】==》微任务==》宏任务=》微任务...
JS作用域考题(重要)
- 除了函数外,js是没有块级作用域。
- 作用域链:内部可以访问外部的变量,但是外部不能访问内部的变量。 注意:如果内部有,优先查找到内部,如果内部没有就查找外部的。
- 注意声明变量是用var还是没有写(window.)
- 注意:js有变量提升的机制【变量悬挂声明】
- 优先级:声明变量 > 声明普通函数 > 参数 > 变量提升
面试的时候怎么看:
- 本层作用域有没有此变量【注意变量提升】
- 注意:js除了函数外没有块级作用域
- 普通声明函数是不看写函数的时候顺序
js作用域考题
##### 考题一:
```
function c(){
var b = 1;
function a(){
console.log( b ); //undefined(变量提升)
var b = 2;
console.log( b ); //2
}
a();
console.log( b ); //1
}
c();
```
##### 考题二:
```
var name = 'a';
(function(){
if( typeof name == 'undefined' ){
var name = 'b';
console.log('111'+name); //111b
}else{
console.log('222'+name); //?
}
})()
```
##### 考题三:
function fun( a ){
var a = 10;
function a(){}
console.log( a ); //10
}
fun( 100 ); //100 参数优先级大
JS对象考题
JS对象注意点:
```
1. 对象是通过new操作符构建出来的,所以对象之间不想等(除了引用外);
2. 对象注意:引用类型(共同一个地址);
3. 对象的key都是字符串类型;
4. 对象如何找属性|方法;
查找规则:先在对象本身找 ===> 构造函数中找 ===> 对象原型中找 ===> 构造函数原型中找 ===> 对象上一层原型查找
```
##### 考题一:
```
[1,2,3] === [1,2,3] //false
```
##### 考题二:
```
var obj1 = {
a:'hellow'
}
var obj2 = obj1;
obj2.a = 'world';
console.log(obj1); //{a:world}
(function(){
console.log(a); //undefined
var a = 1;
})();
```
##### 考题三:
```
var a = {}
var b = {
key:'a'
}
var c = {
key:'c'
}
a[b] = '123';
a[c] = '456';
console.log( a[b] ); // 456
```
JS作用域+this指向+原型 考题
##### 考题一:
```
function Foo(){
getName = function(){console.log(1)} //注意是全局的window.
return this;
}
Foo.getName = function(){console.log(2)}
Foo.prototype.getName = function(){console.log(3)}
var getName = function(){console.log(4)}
function getName(){
console.log(5)
}
Foo.getName(); //2
getName(); //4
Foo().getName(); //1
getName(); //1
new Foo().getName();//3
```
##### 考题二:
```
var o = {
a:10,
b:{
a:2,
fn:function(){
console.log( this.a ); // 2
console.log( this ); //代表b对象
}
}
}
o.b.fn();
```
##### 考题三:
```
window.name = 'ByteDance';
function A(){
this.name = 123;
}
A.prototype.getA = function(){
console.log( this );
return this.name + 1;
}
let a = new A();
let funcA = a.getA;
funcA(); //this代表window
```
##### 考题四:
```
var length = 10;
function fn(){
return this.length + 1;
}
var obj = {
length:5,
test1:function(){
return fn();
}
}
obj.test2 = fn;
console.log( obj.test1() ); //1
console.log( fn()===obj.test2() ); //false
console.log( obj.test1() == obj.test2() ); //false
```
JS判断变量是不是数组,你能写出哪些方法?
写三个差不多了
方式一: isArry (一定要写)
var arr = [1,2,3];
console.log( Array.isArray( arr ) );
方式二: instanceof (可写)
var arr = [1,2,3];
console.log( arr instanceof Array );
方式三: prototype
var arr = [1,2,3];
console.log( Object.prototype.toString.call(arr).indexOf('Array') != -1 ); 是数组
方式四:isPrototypeOf()
var arr = [1,2,3];
console.log( Array.prototype.isPrototypeOf(arr) )
方式五:constructor
var arr = [1,2,3];
console.log( arr.constructor.toString().indexOf('Array') > -1 )
slice是干嘛的、splice是否会改变原数组
面试前数组方法要过一遍
1.slice是用来截取的
参数可以写slice(3),slice(1,3) ,slice(-3)
返回的是一个新数组
- splice 功能有:插入、删除、替换 返回:删除的元素 该方法会改变原数组
arr4在索引值为1的位置删除并且插入一个'你好'
JS数组去重
写个三种差不多了
方式一(最简单): new Set
var arr1 = [1,2,3,4,2,1];
new Set(arr1); //变成Set对象(Set里面的值不重复)
Array.from(new Set(arr1)) //将Set转化为数组
方式二: indexOf
数组中indexOf == -1 就是说明没有重复值
var arr2 = [1,2,3,2,4,1];
function unique( arr ){
var brr = [];
for( var i=0;i<arr.length;i++){
if( brr.indexOf(arr[i]) == -1 ){ //核心步骤,如果这个元素就push
brr.push( arr[i] );
}
}
return brr;
}
console.log( unique(arr2) );
方式三: sort
var arr3 = [1,2,3,2,4,1];
function unique( arr ){
arr = arr.sort(); //[1,1,2,2,3,4]
var brr = [];
for(var i=0;i<arr.length;i++){
if( arr[i] !== arr[i-1]){
brr.push( arr[i] );
}
}
return brr;
}
console.log( unique(arr3) );
找出多维数组最大值
通过forEach + Math.max
function fnArr(arr){
var newArr = [];
arr.forEach((item,index)=>{
newArr.push( Math.max(...item) )
})
return newArr;
}
console.log(fnArr([
[4,5,1,3],
[13,27,18,26],
[32,35,37,39],
[1000,1001,857,1]
]));
给字符串新增方法实现功能
通过原型
给字符串对象定义一个addPrefix函数,当传入一个字符串str时,它会返回新的带有指定前缀的字符串,例如:
console.log( 'world'.addPrefix('hello') ) 控制台会输出helloworld
解答:
String.prototype.addPrefix = function(str){
return str + this;
}
console.log( 'world'.addPrefix('hello') )
找出字符串出现最多次数的字符以及次数(高频)
把字符出现次数放在一个对象里
var str = 'aaabbbbbccddddddddddx';
var obj = {};
for(var i=0;i<str.length;i++){ //循环遍历数组,统计出现次数
var char = str.charAt(i);
if( obj[char] ){
obj[char]++;
}else{
obj[char] = 1;
}
}
console.log( obj ); // {a:3,b:5,c:2,d:10,x:1}
//统计出来最大值
var max = 0;
for( var key in obj ){
if( max < obj[key] ){
max = obj[key];
}
}
//拿最大值去对比
for( var key in obj ){
if( obj[key] == max ){
console.log('最多的字符是'+key);
console.log('出现的次数是'+max);
}
}
new操作符具体做了什么(高频)
- 创建了一个空的对象
- 将空对象的原型,指向于构造函数的原型
- 将空对象作为构造函数的上下文(改变this指向)
- 对构造函数有返回值的处理判断
function Fun( age,name ){
this.age = age;
this.name = name;
}
function create( fn , ...args ){
//1. 创建了一个空的对象
var obj = {}; //var obj = Object.create({})
//2. 将空对象的原型,指向于构造函数的原型
Object.setPrototypeOf(obj,fn.prototype);
//3. 将空对象作为构造函数的上下文(改变this指向)
var result = fn.apply(obj,args);
//4. 对构造函数有返回值的处理判断
return result instanceof Object ? result : obj;
}
console.log( create(Fun,18,'张三') )
闭包
外部函数包裹内容函数,内部函数的作用范围
1. 闭包是什么
闭包是一个函数加上到创建函数的作用域的连接,闭包“关闭”了函数的自由变量(变量不会回收)。
2. 闭包可以解决什么问题【闭包的优点】
2.1 内部函数可以访问到外部函数的局部变量
2.2 闭包可以解决的问题
var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
(function(i){ //内部函数可以访问到外部函数的i
lis[i].onclick = function(){
alert(i);
}
})(i)
}
3. 闭包的缺点
3.1 变量会驻留在内存中,造成内存损耗问题。
解决:把闭包的函数设置为null //lis[i] = null
3.2 内存泄漏【ie】 ==> 可说可不说,如果说一定要提到ie
原型链(最高频)
1.原型可以解决什么问题
解决了共享属性和方法的问题 (new不能共享属性和方法)
2.谁有原型
函数有显示原型 prototype
对象有隐式原型 __proto__
- 对象查找属性或者方法的顺序 先在对象本身查找 --> 对象的构造函数中查找 --> 对象的原型 --> 构造函数的原型中 --> 当前原型的原型中查找
- 原型链 4.1 是什么:就是把原型串联起来 4.2 原型链的最顶端是null
JS继承有哪些方式
方式一: extends
class Parent{
constructor(){
this.age = 18;
}
}
class Child extends Parent{
constructor(){
super();
this.name = '张三';
}
}
let o1 = new Child();
console.log( o1,o1.name,o1.age );
方式二: 原型链继承
function Parent(){
this.age = 20;
}
function Child(){
this.name = '张三'
}
Child.prototype = new Parent(); //子类原型指向父类实例
let o2 = new Child();
console.log( o2,o2.name,o2.age );
方式三: 借用构造函数继承
function Parent(){
this.age = 22;
}
function Child(){
this.name = '张三'
Parent.call(this);
}
let o3 = new Child();
console.log( o3,o3.name,o3.age );
方式四:组合式继承
function Parent(){
this.age = 100;
}
function Child(){
Parent.call(this);
this.name = '张三'
}
Child.prototype = new Parent();
let o4 = new Child();
console.log( o4,o4.name,o4.age );
说一下call、apply、bind区别
共同点: 可以改变函数体this指向
语法: 函数.call()、函数.apply()、函数.bind()
区别:
1.bind不会立即执行
2.apply第二个参数必须是数组
1. call、apply可以立即执行。bind不会立即执行,因为bind返回的是一个函数需要加入() 执行。
2. 参数不同:apply第二个参数必须是数组。call和bind有多个参数需要挨个写。
场景
可说可不说
1. 用apply的情况
var arr1 = [1,2,4,5,7,3,321];
console.log( Math.max.apply(null,arr1) )
2. 用bind的情况
var btn = document.getElementById('btn');
var h1s = document.getElementById('h1s');
btn.onclick = function(){
console.log( this.id );
}.bind(h1s)
sort背后原理是什么?
1.没有参数时候,按照字符编码排序
2.有参数时候
arr.sort(function(a,b)){
return a-b; //从大到小排序
return b-a; //从小到大排序
}
3.参数是对象
sort原理:
V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort。
之前的版本是:插入排序和快排,现在是冒泡
原理实现链接:https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js
***710行代码开始***
深拷贝和浅拷贝
共同点: 复制
区别:
浅拷贝: 两人共用一个地址(只复制引用,而未复制真正的值)
深拷贝 是两个不同地址(是复制真正的值 (不同引用))
1. 浅拷贝:只复制引用,而未复制真正的值。
var arr1 = ['a','b','c','d'];
var arr2 = arr1; //浅拷贝
var obj1 = {a:1,b:2}
var obj2 = Object.assign(obj1);
2. 深拷贝:是复制真正的值 (不同引用)
var obj3 = {
a:1,
b:2
}
var obj4 = JSON.parse(JSON.stringify( obj3 ));
obj3.a = '100';
obj4.b = '你怎么样';
console.log(obj3,obj4);
//递归的形式实现深拷贝
function copyObj( obj ){
//判断是不是数组
if( Array.isArray(obj) ){
var newObj = [];
}else{
var newObj = {};
}
//里面元素是对象或者数组
for( var key in obj ){
if( typeof obj[key] == 'object' ){
newObj[key] = copyObj(obj[key]);
}else{
newObj[key] = obj[key];
}
}
return newObj;
}
console.log( copyObj(obj5) );
localstorage、sessionstorage、cookie的区别
公共点:在客户端存放数据 区别:
-
数据存放有效期 sessionStorage : 仅在当前浏览器窗口关闭之前有效。【关闭浏览器就没了】 localStorage : 始终有效,窗口或者浏览器关闭也一直保存,所以叫持久化存储。 cookie : 只在设置的cookie过期时间之前有效,即使窗口或者浏览器关闭也有效。
-
localStorage、sessionStorage不可以设置过期时间 cookie 有过期时间,可以设置过期(把时间调整到之前的时间,就过期了)
-
存储大小的限制 cookie存储量不能超过4k localStorage、sessionStorage不能超过5M
****根据不同的浏览器存储的大小是不同的。
var、let、const区别(高频)
共同点: var,let,const都是可以声明变量
不同点:
1.变量提升
var有变量提升, let和const没有变量提升
2.多次声明
var可以多次声明, let和const多次声明会报错
3.赋值
var,let是变量,const是常量 不可以再次赋值
//注意const声明的对象里的属性可以改
4.作用域
var声明的变量没有自身作用域 let和const声明的变量有自身的作用域
let和const只在块级作用域生效,var是全局变量
作用域考题
考题一:let和const没有变量提升性
```
console.log( str );//undefined
var str = '你好';
console.log( num );//报错,let和const没有变量提升性
let num = 10;
```
考题二:
```
function demo(){
var n = 2;
if( true ){
var n = 1; //var没有自身作用域
}
console.log( n );//1
}
demo();
function demo(){
let n = 2;
if( true ){
let n = 1; //1只在自身作用域生效
}
console.log( n );//2,
}
demo();
```
考题三:可以修改
```
const obj = {
a:1
}
obj.a = 11111; //可以修改,const对象的属性值可以修改
console.log( obj )
const arr = ['a','b','c'];
arr[0]= 'aaaaa';
console.log( arr );
```
将下列对象进行合并
题目:用你知道的方法合并下列对象
const a={a:1,b:4 }
const b={b:2,c:3 }
方式一:Object.assign
```
const a = {a:1,b:4};
const b = {b:2,c:3};
let obj1 = Object.assign(a,b); //Object.assign合并对象
console.log( obj1 ); //{a:1,b:2,c:3}
```
方式二:...扩展运算符
扩展运算符(...)是ES6的语法,用于取出参数对象的所有可遍历属性,然后拷贝到当前对象之中
```
let obj2 = {...a,...b};
console.log( obj2 );
```
方式三:自己封装方法
```
function extend( target, source ){
for(var key in source){
target[key] = source[key];
}
return target;
}
console.log( extend(a,b) );
```
箭头函数和普通函数有什么区别?(高频)
- this指向的问题 箭头函数中的this只在箭头函数定义时就决定的,而且不可修改的(call、apply、bind) 箭头函数的this指向定义时候、外层第一个普通函数的this
普通函数this指向的是它的直接调用者
2.箭头函数不能new(不能当作构造函数)
3.箭头函数没有prototype原型
4.箭头函数没有arguments对象
Promise相关
小厂: promise几种状态 + promise解决什么问题 + async/await
1.promise几种状态
pending(进行中)
fulfilled(已成功)
rejected(已失败)
2.promise解决什么问题
解决回调地狱问题,可读性和维护性差
3.async/await
比promise和generator代码简洁
find和filter的区别
共同点: 返回新的数据,不改变原数组
区别一: 返回内容不同
find 返回具体的内容
filter 返回的是数组
区别二: 返回时机不同
find :匹配到第一个即返回 (找到就后面不看了) filter : 返回整体(每一个匹配到的都返回)
some和every的区别(大厂)
some ==》 如果有一项匹配则返回true every ==》 全部匹配才会返回true
必考:ES 6 语法知道哪些,分别怎么用?
必考 Promise、Promise.all、Promise.race 分别怎么用?
必考:手写函数防抖和函数节流
如何实现类?
必考:立即执行函数是什么?
必考:什么是 JSONP,什么是 CORS,什么是跨域?
常考:async/await 怎么用,如何捕获异常?
常考:如何用正则实现 trim()?
常考:不用 class 如何实现继承?用 class 又如何实现?
手写系列
手写节流和防抖
手写发布订阅
必考:手写AJAX
手写简化版 promise
手写promise.all
阻止默认事件
阻止事件冒泡
数组常用方法
字符串操作方法
怎么判断数字是不是素数
promise捕获错误几种方式
异步任务有哪些
点击高亮选项卡和图标跟随鼠标移动实现(pink)
4. Vue2+3面试题
Vue2.x 生命周期有哪些?
Vue生命周期都有哪些?
完整解答过程:
1.系统自带了八个生命周期,分别是:
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyed
2.一旦进入组件或者一旦进入页面会执行之前前面4个
beforeCreate
created
beforeMount
mounted
3. 如果使用了keep-alive会多出来两个生命周期
activated
deactivated
4.如果使用了keep-alive第一次进入组件会执行5个生命周期
beforeCreate
created
beforeMount
mounted
activated
5.如果使用了keep-alive第二次或者第N次,每次都会执行一个生命周期
activated
额外附加知识:
在哪个阶段有data
$el :是 用于获取组件内 DOM
beforeCreate 啥也没有
created 开始有$data
beforeMount 同上
mounted 都有了(开始有$el)
谈谈对keep-alive了解?
1.keep-alive是什么
是vue自带的一个组件,功能:是用来缓存组件的 ===> 提升性能
- 使用场景
就是用来缓存组件,提升项目性能。避免多次重复请求
具体实现: 比如当用户从首页进入详情页,如果用户在首页每次点击都是相同的,
那么如果不用keep-alive,就会重复请求相同页面,
因此直接用keep-alive 缓存起来就行,避免多次重复请求
如果点击的不是同一个页面,就直接请求
v-show和v-if是干什么?有什么区别?
使用场景:
v-show :加入购物车、分享、蒙层这种都基本上用v-show v-if : 首页栏目切换的时候v-if
2.1 v-show
显示和隐藏 : display:none进行隐藏 、display:block进行显示
2.2 v-if
创建和删除:remove、append
2.3 区别:
显示和隐藏用:v-show
创建和删除用:v-if
频繁切换用:v-show
不频繁切换用:v-if
首次加载:用v-if,不用v-show
为什么:
如果用v-if可以没有这个盒子,然后再通过v-if进行创建(但是第一次进入页面是没有这个盒子,是不加载的)。
如果用v-show这个盒子不管是显示还是隐藏,该盒子都是在的(节点都是存在)
v-if和v-for优先级(缺)
v-for的优先级要比v-if的优先级高
证明这个事情,是在vue.js源码种10997行
if (el.staticRoot && !el.staticProcessed) {
return genStatic(el, state)
} else if (el.once && !el.onceProcessed) {
return genOnce(el, state)
} else if (el.for && !el.forProcessed) {
return genFor(el, state)
} else if (el.if && !el.ifProcessed) {
return genIf(el, state)
} else if (el.tag === 'template' && !el.slotTarget && !state.pre) {
return genChildren(el, state) || 'void 0'
} else if (el.tag === 'slot') {
return genSlot(el, state)
} else {
注:v-if和v-for不要写在同一个节点上,这个性能很差。(v-if要写在父节点上)
ref是什么?
ref是什么?
获取dom
ref使用场景?
如果项目中使用插件,并且插件是要获取dom的,那么就可以使用ref了。
nextTick是什么?
nextTick是什么?
当dom更新完毕执行内部代码
使用场景:
插件要获取更新后的dom,例如swiper要获取从服务器请求回来的轮播图片
scoped原理
- 作用: 让样式在本组件生效,不影响其他组件
- 原理: 就是给节点加上一个自定义属性,css根据属性选择器添加样式
Vue中如何做样式穿透
stylus样式穿透使用: >>> sass和less使用: /deep/ 通用使用: :v-deep
组件通信
父传子
父传子 props
子传父
子传父 自定义事件 $emit
兄弟组件间
兄弟间 全局事件总线bus.emit
computed、methods、watch有什么区别?
- computed vs methods区别 computed是有缓存的 (多次使用同一个计算属性,只会用第一个的缓存) methods没有缓存
- computed vs watch区别 watch是监听,数据或者路由发生了改变才可以响应(执行) computed计算某一个属性的改变,如果某一个值改变了,计算属性会监听到进行返回 watch是当前监听到数据改变了,才会执行内部代码
一句话: watch强调的是监听的数据/路由 computed强调的是计算的属性
props和data优先级谁高?
优先级 props > data
具体在源码里
vuex相关
vuex是状态管理模式
vuex有哪些属性
state、getters、mutations、actions、modules
state 类似于组件中data,存放数据 getters 类型于组件中computed mutations 类似于组件中methods actions 提交mutations的 modules 把以上4个属性再细分,让仓库更好管理
vuex是单向还是双向数据流
Vuex是单向数据流
vuex中mutaions 和 actions 区别
mutaitons : 都是同步事物 actions : 可以包含任意异步操作,
action提交的是mutation,而不是直接改变状态
***在调试中就看出来
vuex如何做持久化存储
Vuex本身不是持久化存储
- 使用localStorage自己写
- 使用vuex-persist插件
解决跨域问题
?
vue设置代理
slot插槽
使用场景: 组件中有些地方布局可能大多都一致,但是细微有些小变化
Vue路由模式
两种路由模式:history、hash
区别:
1. 表现形态不同
history:http://localhost:8080/about
hash:http://localhost:8080/#/about
2. 跳转请求(路径改变时候)
history : http://localhost:8080/id ===>(404找不到时候)发送请求
hash : 不会发送请求
3. 打包后前端自测要使用hash,如果使用history会出现空白页
介绍一下SPA以及SPA有什么缺点?
SPA是什么Single Page WebApplication?单页面应用 缺点:
1. SEO优化不好
2. 性能不是特别好
vue路径传值
1. 显式:通过query
http://localhost:8080/about?a=1 //显示就是url上有显示
传:this.$router.push({
path:'/about',
query:{
a:1
}
})
接:this.$route.query.a
2. 隐式:通过params
http://localhost:8080/about
传:this.$router.push({
name:'About',
params:{
a:1
}
})
接:this.$route.params.a
路由导航守卫有哪些?
三种路由导航守卫:全局、路由独享、组件内
- 全局 beforeEach、beforeResolve、afterEach
- 路由独享 beforeEnter
- 组件内 beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
使用场景:判断是否登录,如果登录就next否则就跳转到登录页面
vue动态路由
场景:详情页(文章、商品)
router.js配置:
{
path: "/list",
name: "List",
children:[
{
path:"/list/:id", // /list/id 就会跳转到这个路由
name:'Details',
component: () =>
import("../views/Details.vue"),
}
],
component: () =>
import("../views/List.vue"),
},
v-model双向绑定原理
通过Object.defineProperty劫持数据发生的改变,如果数据发生改变了(在set中进行赋值的),触发update方法进行更新节点内容({{ str }}),从而实现了数据双向绑定的原理。
diff算法
太难了,不会
Vue双向绑定和单向绑定
讲一下MVVM框架
web1.0时代
文件全在一起,也就是前端和后端的代码全在一起
问题:
1、前端和后端都是一个人开发。(技术没有侧重点或者责任不够细分)
2、项目不好维护。
3、html、css、js页面的静态内容没有,后端是没办法工作的(没办法套数据)。
mvc....都是后端先出的
web2.0时代
ajax出现了,就可以:前端和后端数据分离了。
解决问题:后端不用等前端页面弄完没,后端做后端的事情(写接口)、前端布局、特效、发送请求。
问题:
1、html、css、js都在一个页面中,单个页面可能内容也是比较多的(也会出现不好维护的情况)。
出现前端的框架了MVC、MVVM
解决问题:可以把一个“特别大”页面,进行拆分(组件化),单个组件进行维护
什么是MVVM
Model-View-的简写
view : 视图【dom==》在页面中展示的内容】
model:模型【数据层:vue中的data数据】
viewModel:视图模型层【就是vue源码】
页面中的内容是通过data展示的
比如说一个str字符串,通过vue源码,把str解析为真正的数据,数据发生改变时候就改变model的数据,从而更新view视图层
必考:Vue 有哪些生命周期钩子函数?分别有什么用?
必考:Vue 数据响应式怎么做到的?
必考:Vue.set 是做什么用的?
Vue2如何实现双向绑定?
Vue3 为什么要用Proxy?
Vue3 为什么要用Composition API?
Vue3 对比 Vue2 有什么改动
说一下自定义指令
路由传参?
5. 其他
HTTP
必考:HTTP 状态码知道哪些?分别什么意思?
大公司必考:HTTP 缓存有哪几种?
必考:GET 和 POST 的区别
Cookie V.S. LocalStorage V.S. SessionStorage V.S. Session
http和https区别
http/1.1 和http/2区别
tcp三次握手和四次握手
安全
必考:什么是 XSS?如何预防?
必考:什么是 CSRF?如何预防?
SQL注入
接口安全
Webpack
必考:有哪些常见 loader 和 plugin,你用过哪些?
英语题:loader 和 plugin 的区别是什么?
必考:如何按需加载代码?
必考:如何提高构建速度?
转义出的文件过大怎么办?
上面五题请看这个不错的参考:zhuanlan.zhihu.com/p/44438844