前端基础面试题

大家好呀,马上要找工作了,复习了几天学过的知识点,今天来整理一下刷过的面试题,顺便分享给大家,希望能对你们有所帮助。
好了,话不多说,直接开始吧!

1.cookie sessionStorage localStorage 区别

共同点:
Cookie、LocalStorage、 SessionStorage都是浏览器的本地存储,数据共享都遵循同源原则。

区别:
Cookie:由服务器端写入,生命周期在写入时就已经设置好了,存储空间大概4kb,在前端给后端发送请求的时候会自动携带Cookie中的数据,Cookie一般用于存储登录验证信息SessionID或者token。

LocalStorage:由前端写入,生命周期在写入时就一直存在,除非手动清除,存储空间大概5m,LocalStorage常用于存储不易变动的数据,减轻服务器的压力。

SessionStorage:由前端写入,生命周期在页面关闭时自动清除,存储空间和LocalStorage一样,大概5m;数据共享必须在同一页面;SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能。

2.同源策略

同源指的是域名、协议、端口号相同

3.JS数据类型有哪些

JS数据类型分为两类:一类是基本数据类型,也叫简单数据类型,另一类是引用数据类型也叫复杂数据类型。

简单数据类型:包含7种类型,分别是Number 、String、Boolean、Null、Undefined、BigInt、Symbol。

引用数据类型:通常用Object代表,普通对象,数组,正则,日期,Math数学函数都属于Object。

4.闭包

闭包基本上就是一个函数内部return另一个函数,被return出去的函数能够在外部访问函数内部的变量,函数执行结束后这个变量背包也不会被销毁,并且这个变量背包在A函数外部只能通过B函数访问。

好处:
可以读取函数内部的变量;
将变量始终保持在内存中;
可以封装对象的私有属性和私有方法。

坏处:
比较耗费内存、使用不当会造成内存溢出的问题。

5.js变量、函数声明的提升

在js中变量和函数的声明会提升到最顶部执行,函数的提升高于变量的提升,函数内部如果用 var 声明了相同名称的外部变量,函数将不再向上寻找,匿名函数不会提升。

6.== 和 ===的区别

==:值相等就相等。

===:值和引用地址相等才相等。

7.跨域是什么?如何解决跨域问题?

跨域:当前页面中的某个接口请求的地址和当前页面的地址如果协议、域名、端口其中有一项不同,就说该接口跨域了。

跨域限制的原因:浏览器为了保证网页的安全,出的同源协议策略。

跨域解决方案
cors:目前最常用的一种解决办法,通过设置后端允许跨域实现。
res.setHeader(‘Access-Control-Allow-Origin’, ‘*’);
res.setHeader(“Access-Control-Allow-Methods”, “GET, PUT, OPTIONS, POST”);

node中间件、nginx反向代理:跨域限制的时候浏览器不能跨域访问服务器,node中间件和nginx反向代理,都是让请求发给代理服务器,静态页面面和代理服务器是同源的,然后代理服务器再向后端服务器发请求,服务器和服务器之间不存在同源限制。

JSONP:利用的原理是script标签可以跨域请求资源,将回调函数作为参数拼接在url中。后端收到请求,调用该回调函数,并将数据作为参数返回去,注意设置响应头返回文档类型,应该设置成javascript。

postmessage:H5新增API,通过发送和接收API实现跨域通信。

8.BFC

BFC(Block Formatting Context)块级格式化上下文,是Web页面一块独立的渲染区域,内部元素的渲染不会影响边界以外的元素。

形成BFC条件:float、position、overflow、display

9.清除浮动的方式

(1)使用clear:both清除浮动

<div style="clear: both"></div>

(2)利用伪元素来清除浮动

.clearfix:after{
    content:"";
    display:block;
    visibility:hidden;
    clear:both;
}

(3)overflow方法

.box{
	overflow: auto
	或者
	overflow:hidden
}

(4)双伪元素方法的使用

.clearfix:before,.clearfix:after {
     content: "";
     display: block;
     clear: both;
}

10.JavaScript有几种方法判断变量的类型

typeof:常用于判断基本数据类型,对于引用数据类型除了function返回’function‘,其余全部返回’object’。

instanceof:主要用于区分引用数据类型,检测方法是检测的类型在当前实例的原型链上,用其检测出来的结果都是true,不太适合用于简单数据类型的检测,检测过程繁琐且对于简单数据类型中的undefined, null, symbol检测不出来。

constructor:用于检测引用数据类型,检测方法是获取实例的构造函数判断和某个类是否相同,如果相同就说明该数据是符合那个数据类型的,这种方法不会把原型链上的其他类也加入进来,避免了原型链的干扰。

Object.prototype.toString.call():适用于所有类型的判断检测,检测方法Object.prototype.toString.call() 返回的是该数据类型的字符串。

11.样式优先级的规则

!important > 内联样式(style) > ID选择器(id) > 类选择器(class) > 标签选择器

12.JS实现异步的方法

回调函数
优点:简单、容易理解
缺点:不利于维护、代码耦合高

事件监听
优点:容易理解,可以绑定多个事件,每个事件可以指定多个回调函数
缺点:事件驱动型,流程不够清晰

发布/订阅(观察者模式)
类似于事件监听,但是可以通过‘消息中心’,了解现在有多少发布者,多少订阅者

Promise 对象
优点:可以利用 then 方法,进行链式写法;可以书写错误时的回调函数
缺点:编写和理解,相对比较难

Generator 函数
优点:函数体内外的数据交换、错误处理机制
缺点:流程管理不方便

async 函数
优点:内置执行器、更好的语义、更广的适用性、返回的是 Promise、结构清晰
缺点:错误处理机制

13.数组去重

var arr = [1,8,5,6,1,2,3,5,4,8,9,8,5,4,7,2,3,5,4,6]

(1).使用ES6的 Set方法 (new Set())

function qc1(){
    return Array.from(new Set(arr)) 
}
console.log(qc1())

(2).双循环----双重循环 + splice (返回修改后的参数数组)

function qc2(){
    for(let i=0;i<arr.length;i++){
        for(let j=i+1;j<arr.length;j++){
            if(arr[i] == arr[j]){
                arr.splice(j,1);
                j--;
            }
        }
    }
    return arr
}
console.log(qc2())

(3).单循环+indexof----新建一个只有原数组第一项的新数组 + 循环原数组 + indexof判断每项是否在新数组中已经存在,不存在则推入新数组

var arr1 = [arr[0]]
function qc3(){
    for(let i=1;i<arr.length;i++){
        if(arr1.indexOf(arr[i]===-1)){
            arr1.push(arr[i])
            // console.log(arr1)
        }
    }
    return arr1
}
console.log(qc3())

(4).利用判断对象属性是否存在的方法 + 新数组

var arr2 = []
var obj = {}
function qc4(){
    for(let i=0;i<arr.length;i++){
        if(!obj[arr[i]]){
            obj[arr[i]] = 123;
            arr2.push(arr[i])
        }
    }
    return arr2
}
console.log(qc4())

14.null 和 undefined 的区别

undefind 是全局对象的一个属性,当一个变量没有被赋值或者一个函数没有返回值或者某个对象不存在某个属性却去访问或者函数定义了形参但没有传递实参,这时候都是undefined。

null代表对象的值未设置。

undefined 表示一个变量初始状态值,而 null 则表示一个变量被人为的设置为空对象,而不是原始状态。

15.浮动

脱离文档流、盒子塌陷、 影响其他元素排版。

16.箭头函数

没有this,this是从外部获取;

不能使用new;

没有arguments;

没有原型和super。

17.call apply bind的作用和区别

call、apply、bind的作用都是改变函数运行时的this指向。

1、fn.call (newThis,params) call函数的第一个参数是this的新指向,后面依次传入函数fn要用到的参数。会立即执行fn函数。

2、fn.apply (newThis,paramsArr) apply函数的第一个参数是this的新指向,第二个参数是fn要用到的参数数组,会立即执行fn函数。

3、fn.bind (newThis,params) bind函数的第一个参数是this的新指向,后面依次传入函数fn要用到的参数。 不会立即执行fn函数,且只能改变一次fn函数的指向,后续再用bind更改无效。

18.事件委托、事件冒泡、事件捕获、

事件委托:利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
事件冒泡:事件从最里层的后代逐层传出
事件捕获:事件从最外面的父依次传递到最里面的后代

19.常用数组api

concat(): 连接两个或更多的数组,并返回结果。

join(): 把数组的所有元素放入一个字符串。

push(): 可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。

pop():数组末尾移除最后一项,减少数组的 length 值,然后返回移除的项。

shift():删除原数组第一项,并返回删除元素的值;如果数组为空则返回undefined 。

unshift():将参数添加到原数组开头,并返回数组的长度 。

sort():按升序排列数组项——即最小的值位于最前面,最大的值排在最后面。

reverse():反转数组项的顺序。

slice():返回从原数组中指定开始下标到结束下标之间的项组成的新数组。slice()方法可以接受一或两个参数,即要返回项的起始和结束位置。在只有一个参数的情况下, slice()方法返回从该参数指定位置开始到当前数组末尾的所有项。如果有两个参数,该方法返回起始和结束位置之间的项——但不包括结束位置的项。

splice():很强大的数组方法,它有很多种用法,可以实现删除、插入和替换。删除功能,第一个参数为第一项位置,第二个参数为要删除几个。插入功能,第一个参数(插入位置),第二个参数(0),第三个参数(插入的项)。

split() 方法用于把一个字符串分割成字符串数组。

删除:可以删除任意数量的项,只需指定 2 个参数:要删除的第一项的位置和要删除的项数。例如, splice(0,2)会删除数组中的前两项。

插入:可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、 0(要删除的项数)和要插入的项。例如,splice(2,0,4,6)会从当前数组的位置 2 开始插入4和6。

替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起始位置、要删除的项数和要插入的任意数量的项。

indexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的开头(位置 0)开始向后查找。

lastIndexOf():接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。其中, 从数组的末尾开始向前查找。

20.创建对象的5种方法

1: Object构造函数模式

var 对象变量名 = new Object()
对象变量名.name = zz
...

2: 对象字面量模式

var 对象变量名 = {
	name:aa,
	age:18;
	...
}

3: 构造方法模式

function student(name,mobile){
	this.name=name;
	...
}
var student=new student("jim","111");

4: 原型式

function Student(){}
Student.prototype.name="jim";
...
var student=new Student();

5: 构造函数+原型的组合模式

function Student(name,mobile){
	this.name=name;
	this.mobile=mobile;
}
Student.prototype.dohomework=function(){
	console.log(this.name+"做作业吧。。。")
}
var student=new Student("jim","333");

21.虚拟dom diff算法

虚拟DOM实际上就是一个JS对象,用来描述真实DOM,如果操作中有多次更新DOM的动作,会用diff算法进行比对,根据新的内容生成一个新的虚拟DOM(createElement),最终把这个虚拟DOM一次性attch到DOM树上,这样就大大节省了性能。

虚拟DOM比对中用到了diff算法,diff实际上就是diffrence的意思,就是做对比找差异,diff算法中有一个很重要的原理就是同级比对,能达到这种效果的原因就是在每个dom上添加了key值用来做对比,产生的差异会生成一个新的patch文件

22.vue-route 路由守卫

  1. 全局前置守卫
router.beforeEach([to][, from][, next])
  1. 全局解析守卫
router.beforeResolve([to][, from][, next])
  1. 全局后置守卫
router.afterEach([to][, from][, failure])
  1. 路由独享守卫
beforeEnter([to][, from][, next])
  1. 组件前置路由守卫
beforeRouteEnter(to, from, next)
  1. 组件路由更新守卫
 beforeRouteUpdate(to, from)
  1. 组件后置路由守卫
beforeRouteLeave([to][, from][, next])
  1. 调用顺序

进入组件
beforeEach
-> beforeRouterEnter
-> beforeResolve
-> afterEach
-> beforeCreate ( 组件lifecycle )

离开组件
beforeRouterLeave
-> beforeEach
-> beforeResolve
-> afterEach
-> beforeDestory ( 组件lifecycle )

23.vue生命周期

1 beforeCreate(创建前)

2 created(创建后)

3 beforeMount(载入前)

4 mounted(载入后)

5 beforeUpdate(更新前)

6 updated(更新后)

7 beforeDestroy(销毁前)

8 destroyed(销毁后)

24.vuex

1.state :数据存贮

2.getter :state的计算属性

3.mutation :更改state中状态的逻辑 同步操作

4.action: 提交mutation 异步操作

5.model :模块化

25.MVVM和MVM

MVC:view -> controller -> model -> view

MVP:view <=> Presenter <=> model

MVVM:view <=> ViewModel <=> model

其中,mvc是单项通信,mvp和mvvm中的view层都不与model层有交互,都是通过中间的Presenter(ViewModel)来实现数据交互,mvvm还可以实现数据的双向绑定。

26.vue组件中数据共享的方式

1、父组件向子组件共享数据,需要使用自定义属性props来接收

2、子组件向父组件共享数据,使用自定义事件
子组件使用$emit向父组件传参,第一个参数为方法名,第二个参数为需要传递的值

3、兄弟组件之间的数据共享,使用EventBus
(1.创建 eventBus.js 模块,并向外共享一个 Vue 的实例对象
(2. 在数据发送方,调用 bus.$emit(‘事件名称', 要发送的数据) 方法触发自定义事件
(3.在数据接收方,调用 bus.$on(‘事件名称', 事件处理函数) 方法注册一个自定义事件

27.get与post的区别

get是从服务器上获取数据,传输量小,安全性低

post是向服务器发送数据,传输量大,安全性比get要高

28.怪异盒模型和标准盒模型的区别

box-sizing:content-box; 将采用标准模式的盒子模型标准

box-sizing:border-box; 将采用怪异模式的盒子模型标准

box-sizing:inherit; 规定应从父元素继承 box-sizing 属性的值。

标准盒大小计算公式:width(content) + padding + border + margin

怪异盒大小的计算公式:width(content + padding + border) + margin

29.Commonjs和ES6 Module的区别

  1. CommonJs模块的require()是同步加载模块,ES6模块的import命令是异步加载模块

  2. CommonJs模块是运⾏时加载,ES6模块是编译时加载或静态加载

  3. CommonJs模块加载有缓存,ES6模块加载没有缓存

  4. CommonJs模块输出的是⼀个值的复制,ES6模块输出的是值的只读引⽤

  5. CommonJs加载的是整个模块,即将所有的⽅法都加载进来,ES6可以单独加载其中的某个⽅法

  6. CommonJs模块中this指向当前模块,ES6中指向undefined

30.promise和async await区别

  1. async/await是写异步代码的新方式,以前的方法有回调函数和promise

  2. async/await是基于promose实现的,他不能用于普通的函数

  3. async/await与promise一样,是非阻塞的

  4. async/await使得异步代码看起来像同步代码

  5. 函数的前面多了一个aynce关键字。await关键字只能用在aync定义的函数内。async函数会隐士地返回一个promise,该promise的reosolve值就是函数return的值。

  6. await只能在aync函数内使用

  7. promise不能在返回表达式的箭头函数中设置断点

  8. 如果你在.then代码块中设置断点,进入下一步的话,调试器不会跳到下一个.then,因为他只会跳过异步代码。

  9. 使用async/await时,不在需要那么多的箭头函数,这样调试就像调试同步代码一样。

31.http和https

  1. https协议需要到ca申请证书,一般免费证书很少,需要交费。

  2. http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议

  3. http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。

  4. http的连接很简单,是无状态的

  5. HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全

32.三列布局

1、⾃⾝浮动法
思路:对左右分别使⽤float:left和float:right,float使左右两个元素脱离⽂档流,中间盒⼦是正常⽂档流。在html结构中,中间的盒⼦⼀定要放置在左右盒⼦的后⾯。这样中间的盒⼦会⾃动移动到左右盒⼦下⾯,并且使⽤margin指定左右外边距进⾏定位,以便留出左右盒⼦的宽度,从⽽使中间元素⾃适应屏幕宽度。

2、绝对定位法:
思路:和浮动法的思路差不多,只不过这⾥使⽤绝对定位将使左右盒⼦脱离⽂档流,并且html结构中盒⼦放置顺序是左,中,右

3、flex布局(推荐)
给⽗容器设置样式display:flex,justify-content: space-between。

4、圣杯布局
圣杯布局的原理是margin负值法。为了让中间盒⼦内容不被遮挡,设置⽗盒⼦padding:0 200px,使中间盒⼦左右两边空出200px区域以便放置左右盒⼦。并且html结构中盒⼦放置顺序是中,左,右,并且全部左浮动。然后设置左盒⼦的 左负外边距,并加上定位,设置右盒⼦右负外边距。

5、双飞翼布局
双飞翼布局是为了解决圣杯布局的弊端提出的,如果在圣杯布局中将浏览器宽度缩短到⼀定程度的时候,会使得中间⼦元素的宽度⽐左右⼦元素宽度⼩的时候,这时候布局就会出现问题。但是双飞翼布局缺点是:多加了⼀层dom节点。所以这⾥提⽰在使⽤圣杯布局的时候⼀定要设置整个容器的最⼩宽度。
思路类似圣杯布局,但是为了中间div内容不被遮挡,需在中间div盒⼦内部创建⼦盒⼦,并在该⼦盒⼦⾥⽤margin-left和margin-right为左右两栏div留出位置。同时,左右两栏盒⼦只⽤到了左负边距。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值