个人整理100道前端面试题 希望给面试的小伙伴有所帮助喜欢的话就点个关注会持续更新分享一些前端
0、css布局方式
1、table布局(现在少用)
2、flex布局
3、float布局
4、响应式布局
1、说一下盒子模型(常问)
标准和模型和IE盒子模型
这两个的区别主要是
IE盒子模型的宽高包括content和padding还有border,标准盒子模型 不包括,
box-sizing:content-box 标准盒模型
box-sizing:border-box IE盒模型
3、浏览器运行机制
1、创建DOM树
2、构建渲染树,CSS渲染
3、布局渲染,每个元素的大小、位置
4、绘制渲染树、再画出来
重绘:改变元素的外观属性例如div的color、background-color、等属性发生改变时
重排(回流):元素的规模尺寸、布局、隐藏改变时
代价:耗时,导致浏览器卡慢
4、居中的方式
垂直居中的方式
行高=高
Margin auto 0
绝对定位 top50%,自身宽度的50%的负值
flex布局 align—center
水平居中的方式
绝对定位
flex布局 juest—center
margin 0 auto
text-align center
5、清除浮动的方法
方法一:使用带 clear 属性的空元素
在浮动元素后使用一个空元素,并在 CSS 中赋 予.clear{clear:both;}属性即可清理浮动。
方法二:使用 CSS 的 overflow 属性
给浮动元素的容器添加 overflow:hidden;或 overflow:auto;可以清除浮动,另外在 IE6 中还 需要触发 hasLayout ,例如为父元素设置容器宽高或设置 zoom:1。在添加 overflow 属性后,浮动元素又回到了容器层,把容器高度撑起,达到了清理浮动 的效果。
方法三:给浮动的元素的容器添加浮动
给浮动元素的容器也添加上浮动属性即可清除内部浮动,但是这样会使其整体浮动,影 响布局,不推荐使用。
方法四:使用 CSS 的:after 伪元素
结合:after 伪元素(注意这不是伪类,而是伪元素,代表一个元素之后最近的元素)和 IEhack ,可以完美兼容当前主流的各大浏览器,这里的 IEhack 指的是触发 hasLayout。给浮动元素的容器添加一个 clearfix 的 class,然后给这个 class 添加一个:after 伪元素实 现元素末尾添加一个看不见的块元素清除浮动
6、ES6新增了哪些方法
1、includes()用于判断数组是否包含给定的值 返回一个布尔值
2、find()用于找出第一个符合条件的数组成员
3、findindex()返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1
4、set数据结构,类似于数组,但是成员的值都是唯一的,没有重复的值
5、、let声明变量、const声明常量(这里就要问你var、let、const的区别了)
6、解构赋值 …
set 和map 的区别!!!以前被问没看过,懵逼过,所以要记住
1.Map是键值对,Set是值的集合,键和值可以是任何的值;
2.Map可以通过get方法获取值,而set不能因为它只有值,set只能用has来判断,返回一个布尔值;
4.Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储
7、Var、 let 、const 区别?
var、let、const三者区别可以围绕下面五点展开:
变量提升
var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined
let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错
暂时性死区
var不存在暂时性死区
let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
块级作用域
var不存在块级作用域
let和const存在块级作用域
重复声明
var允许重复声明变量
let和const在同一作用域不允许重复声明变量
修改声明的变量
var和let可以
const声明一个只读的常量。一旦声明,常量的值就不能改变
使用
能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var
7、== 和 ===区别
相等操作符()会做类型转换,再进行值的比较,全等运算符(=)不会做类型转换
let result1 = (“55” === 55); // false,不相等,因为数据类型不同
let result2 = (55 === 55); // true,相等,因为数据类型相同值也相同
null 和 undefined 比较,相等操作符(==)为true,全等为false
let result1 = (null == undefined ); // true
let result2 = (null === undefined); // false
8去重方法
1、利用ES6 Set去重(ES6中最常用)
function unique (arr) {
return Array.from(new Set(arr))
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {}, {}]
2、利用for嵌套for,然后splice去重(ES5中最常用)
function unique(arr){
for(var i=0; i<arr.length; i++){
for(var j=i+1; j<arr.length; j++){
if(arr[i]==arr[j]){ //第一个等同于第二个,splice方法删除第二个
arr.splice(j,1);
j--;
}
}
}
return arr;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", 15, false, undefined, NaN, NaN, "NaN", "a", {…}, {…}] //NaN和{}没有去重,两个null直接消失了
3、利用indexOf去重
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var array = [];
for (var i = 0; i < arr.length; i++) {
if (array .indexOf(arr[i]) === -1) {
array .push(arr[i])
}
}
return array;
}
var arr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
// [1, "true", true, 15, false, undefined, null, NaN, NaN, "NaN", 0, "a", {…}, {…}] //NaN、{}没有去重
9、利用includes
function unique(arr) {
if (!Array.isArray(arr)) {
console.log('type error!')
return
}
var array =[];
for(var i = 0; i < arr.length; i++) {
if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
array.push(arr[i]);
}
}
return array
}
vararr = [1,1,'true','true',true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,'NaN', 0, 0, 'a', 'a',{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}]
10、bind、call、apply 区别
1.call和apply会调用函数,且会改变函数内部的this指向
2.call和apply传递的参数不一样,call传递参数aru1,aru2.形式 而apply必须是数组形式[arg]
3.bind 不会调用函数,可以改变函数内部指向
应用场景:
1.call经常做继承
2.apply经常和数组有关系,比如借助于数学对象实现数组的max、min
3.bind不调用函数,但改变this指向,比如改变定时器内部的this指向
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即 A 对象应用 B 对象的方法。call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2); 即 A 对象调用 B 对象的方法。bind 除了返回是函数以外,它的参数和 call 一样。
11、本地存储的方式有哪些?区别及应用场景?
javaScript本地缓存的方法我们主要讲述以下四种:
cookie
sessionStorage
localStorage
indexedDB
区别:
关于cookie、sessionStorage、localStorage三者的区别主要如下:
存储大小:cookie数据大小不能超过4k,sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
有效时间:localStorage存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage数据在当前浏览器窗口关闭后自动删除;cookie设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
数据与服务器之间的交互方式,cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端;sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
13、说说你对闭包的理解?闭包使用场景
闭包就是函数中包含另一个函数,可以让你在函数外部读取到内部的变量(就是在函数内部再定义一个函数),让这些变量的值始终保持在内存中,可以达到延长变量生命周期的效果,过多使用会导致内存泄漏的问题
(在创建私有变量和想延长变量的生命周期时会用到闭包)
14、深拷贝浅拷贝的区别?
**浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝
如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址
在JavaScript中,存在浅拷贝的现象有:
Object.assign
Array.prototype.slice()
Array.prototype.concat()
使用拓展运算符实现的复制
深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性
常见的深拷贝方式有:
_.cloneDeep()
jQuery.extend()
JSON.stringify()
手写循环递归
15、JavaScript中的数据类型?
string、number、Boolean、undefined、null、object
16、 JavaScript 中内存泄漏的几种情况?
使用闭包
17、原型,原型链 ? 有什么特点?
JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象
当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾
原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法
18、如何实现上拉加载,下拉刷新?
开源社区有很多优秀的解决方案,如iscroll、better-scroll、pulltorefresh.js库等等
19、说说你对作用域链的理解
1、作用域就是变量与函数的可访问范围
2、一般情况下,变量取值到创建这个变量的函数的作用域中取值。但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链
20、typeof 与 instanceof 区别
typeof与instanceof都是判断数据类型的方法,区别如下:
typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
而typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断
17、js基本数据类型
string、number、null、defined、boolean、object、symbol、bigint
21、ajax、axios、jsonp的理解
1、jsonp是一种可以解决跨域问题的方式,就是通过动态创建script标签用src引入外部文件实现跨域,script加载实际上就是一个get请求,并不能实现post请求。(其他实现跨域的方法有:iframe,window.name,postMessage,CORS…)
2、ajax是一种技术,ajax技术包含了get和post请求的,但是它仅仅是一种获取数据的技术,不能直接实现跨域,只有后台服务器配置好Access-Control-Allow-Origin,才可以实现请求的跨域。
4、axios是通过promise实现对ajax技术的一种封装,axios是ajax,ajax不止axios。
总结:
juery的$.ajax实现get请求能跨域是因为jsonp或者因为原生ajax和服务器的配合,post请求能跨域就只能是因为原生ajax和服务器的配合。
22、ajax的请求过程
// ajax 提交 post 请求的数据
// 1. 创建核心对象
var xhr = new XMLHttpRequest();
// 2. 准备建立连接
xhr.open("POST", "register.php", true);
// 3. 发送请求
// 如果要POST提交数据,则需要设置请求头
// 有的面试官会问为什么要设置请求头?知道请求正文是以什么格式
// Content-Type: application/x-www-form-urlencoded,请求正文是类似 get 请求 url 的请求参数
// Content-Type: application/json,请求正文是一个 json 格式的字符串
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 发送数据
xhr.send(querystring);
// 4. 处理响应
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { // 请求处理完毕,响应就绪
if (xhr.status === 200) { // 请求成功
var data = xhr.responseText;
console.log(data);
}
}
}
23、ajax请求的时候get 和post方式的区别
1、get请求不安全,post安全 ;
2、get请求数据有大小限制,post无限制 ;
3、get请求参数会在url中显示,容易被他人窃取,post在请求体中,不会被窃取;
4、post需要设置请求头。
24、为什么使用虚拟DOM(常问)
创建真实DOM的代价高:真实的 DOM 节点 node 实现的属性很多,而 vnode 仅仅实现一些必要的属性,相比起来,创建一个 vnode 的成本比较低。
触发多次浏览器重绘及回流:使用 vnode ,相当于加了一个缓冲,让一次数据变动所带来的所有 node 变化,先在 vnode 中进行修改,然后 diff 之后对所有产生差异的节点集中一次对 DOM tree 进行修改,以减少浏览器的重绘及回流。
虚拟dom由于本质是一个js对象,因此天生具备跨平台的能力,可以实现在不同平台的准确显示。
Virtual DOM 在性能上的收益并不是最主要的,更重要的是它使得 Vue 具备了现代框架应有的高级特性。
25、vue常用的组件通信
vararr = [1,1,‘true’,‘true’,true,true,15,15,false,false, undefined,undefined, null,null, NaN, NaN,‘NaN’, 0, 0, ‘a’, ‘a’,{},{}];
console.log(unique(arr))
//[1, "true", true, 15, false, undefined, null, NaN, "NaN", 0, "a", {…}, {…}] ue组件通信
父组件向子组件传值
父组件发送的形式是以属性的形式绑定值到子组件身上。
然后子组件用属性props接收
在props中使用驼峰形式,模板中需要使用短横线的形式字符串形式的模板中没有这个限制
子组件向父组件传值
子组件用$emit()触发事件
$emit() 第一个参数为 自定义的事件名称 第二个参数为需要传递的数据 $(event)来接收
父组件用v-on 缩写为@ 监听子组件的事件
兄弟之间的传递
兄弟之间传递数据需要借助于事件中心,通过事件中心传递数据
提供事件中心 var hub = new Vue()
传递数据方,通过一个事件触发hub.$emit(方法名,传递的数据)
接收数据方,通过mounted(){} 钩子中 触发hub.$on()方法名
销毁事件 通过hub.$off()方法名销毁之后无法进行传递数据
26、Vue中key是用来做什么的?为什么不推介使用index作为key?
1、key的作用主要是为了高效的更新虚拟DOM(使用key,它会基于key的变化重新排列元素顺序,并且会移除key不存在的元素)
2、当以数组的下标index作为index值时,其中一个元素(如增删改查)发生了变化就有可能导致所有元素的key值发生变化
4、生命周期:
从Vue实例创建、运行、到销毁期间,伴随着的各种事件,这些事件统称为生命周期
生命周期函数分类:
创建期间的生命周期函数:
beforeCreate:实例刚在内存中被创建出来,此时还没有初始化好data和methods属性
created:实例已经在内存中创建出来,此时的data和methods以及创建完成,但是还没有开始编译模板
beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面上
mounted:已经将编译好的模板,挂载到了页面指定的容器中显示
运行期间的生命周期函数:
beforeUpdate:状态更新之前执行此函数,此时data中的状态值是最新的,但是界面上显示的数据还是旧的,因为此时还没有开始重新渲染DOM节点
updated:实例更新完毕之后调用此函数,此时data中的状态值和界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了
销毁期间的生命周期函数:
注意 !!!vue3,则是beforeunmount和unmount
beforeDestory:实例销毁之前调用,在这一步,实例仍然完全可用
destroyed:Vue实例销毁之后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁
27、v-show和v-if的区别
v-show原理是修改元素的css属性display:none来决定是显示还是隐藏
v-if则是通过操作DOM来进行切换显示
28、双向数据绑定
实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
29、Vue导航守卫的钩子函数有哪些?
全局守卫
router.beforeEach:全局前置守卫,进入路由之前
router.beforeResolve:全局解析守卫,在beforeRouteEnter调用之后调用
router.afterEach:全局后置钩子,进入路由之后
路由组件内的守卫
beforeRouteEnter():进入路由前
beforeRouteUpdate():路由复用同一个组件时
beforeRouteLeave():离开当前路由时
30、vue编程式的导航跳转传参的方式有哪些?
// 命名的路由
router.push({ name: ‘user’, params: { userId: ‘123’ }})
// 带查询参数,变成 /register?plan=private
router.push({ path: ‘register’, query: { plan: ‘private’ }})
31、vuex是什么?怎么使用?哪种功能场景使用它?
在main.js引入store,注入。新建了一个store目录,然后…… export 。场景:单页应用中,组件之间的共享状态和方法 state Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。mutations mutations定义的方法动态修改Vuex 的 store 中的状态或数据。getters 类似vue的计算属性,主要用来过滤一些数据。action actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。modules 项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
32、mvc和mvvc的区别
MVC
MVC包括view视图层、controller控制层、model数据层。各部分之间的通信都是单向的。
View 传送指令到 Controller Controller 完成业务逻辑后,要求 Model 改变状态 Model 将新的数据发送到 View,用户得到反馈
MVVM
MVVM包括view视图层、model数据层、viewmodel层。各部分通信都是双向的。
采用双向数据绑定,View的变动,自动反映在 ViewModel,反之亦然。mvvm代表框架:Angularjs、React、Vue mvvm主要解决了mvc中大量 dom操作使得页面渲染性能降低,加载速度变慢,影响用户体验
33、说出至少vue 3个常用事件修饰符?
.stop 阻止点击事件冒泡
.prevent 阻止默认事件
.once 只执行一次
.self 只在元素本身触发
34、vuex有哪几种属性
有五种,分别是State , Getter , Mutation , Action , Module (就是mapAction)
state:vuex的基本数据,用来存储变量
geeter:从基本数据(state)派生的数据,相当于state的计算属性
mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
action:和mutation的功能大致相同,不同之处在于 ==》1. Action 提交的是 mutation,而不是直接变更状态。2. Action 可以包含任意异步操作。
modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
35、说一下http和https
http:超文本传输协议,是一个客户端和服务器端请求和应答的标准(TCP)
https:是以安全为目标的HTTP通道,即HPPT下加入SSL层,比http更安全
区别:
http传输的数据都是未加密的(明文),https协议是由https和SSL协议构建的可进行加密传输和身份认证的网络协议,需要ca证书,费用较高
36、tcp三次握手,一句话概括
客户端和服务端都需要直到各自可收发,因此需要三次握手
37、HTTP状态码
1xx Informational(信息性状态码) 接受的请求正在处理
2xx Success(成功状态码) 请求正常处理完毕
(1)、200 OK:表示从客户端发送给服务器的请求被正常处理并返回;
(2)、204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回);
(3)、206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。
3xx Redirection(重定向) 需要进行附加操作以完成请求
(1)、301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;
(2)、302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;
(3)、301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)
(4)、303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;
(5)、302与303的区别:后者明确表示客户端应当采用GET方式获取资源
(6)、304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码;
(7)、307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况);
4xx Client error(客户端错误) 客户端请求出错,服务器无法处理请求
400 Bad Request:表示请求报文中存在语法错误;
401 Unauthorized:未经许可,需要通过HTTP认证;
403 Forbidden:服务器拒绝该次访问(访问权限出现问题)
404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;
5xx Server Error(服务器错误) 服务器处理请求出错
500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时;
503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求;
38:画一个三角形?
这属于简单的css考查,平时在用组件库的同时,也别忘了原生的css
.a{
width: 0;
height: 0;
border-width: 100px;
border-style: solid;
border-color: transparent #0099CC transparent transparent;
transform: rotate(90deg); /*顺时针旋转90°*/
}
<div class="a"></div>
39用js递归的方式写1到100求和?
递归我们经常用到,vue在实现双向绑定进行数据检验的时候用的也是递归,但要我们面试的时候手写一个递归,如果对递归的概念理解不透彻,可能还是会有一些问题。
function add(num1,num2){
var num = num1+num2;
if(num2+1>100){
return num;
}else{
return add(num,num2+1)
}
}
var sum =add(1,2);
40说一下CORS?
CORS是一种新标准,支持同源通信,也支持跨域通信。fetch是实现CORS通信的
42如何中断ajax请求?
一种是设置超时时间让ajax自动断开,另一种是手动停止ajax请求,其核心是调用XML对象的abort方法,ajax.abort()
43说一下事件代理?
事件委托是指将事件绑定到目标元素的父元素上,利用冒泡机制触发该事件
ulEl.addEventListener(‘click’, function(e){
var target = event.target || event.srcElement;
if(!!target && target.nodeName.toUpperCase() === "LI"){
console.log(target.innerHTML);
}
}, false);
44export和export default的区别?
使用上的不同
export default xxx
import xxx from ‘./’
export xxx
import {xxx} from ‘./’
45说一下自己常用的es6的功能?
此题是一道开放题,可以自由回答。但要注意像let这种简单的用法就别说了,说一些经常用到并有一定高度的新功能
像module、class、promise等,尽量讲的详细一点。
46什么是会话cookie,什么是持久cookie?
cookie是服务器返回的,指定了expire time(有效期)的是持久cookie,没有指定的是会话cookie
46、简述一下src与href的区别
href 是指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,用于超链接。
src是指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素。当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部。
47、简述同步和异步的区别
同步是阻塞模式,异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
48、px和em的区别
px和em都是长度单位,区别是,px的值是固定的,指定是多少就是多少,计算比较容易。em得值不是固定的,并且em会继承父级元素的字体大小。
浏览器的默认字体高都是16px。所以未经调整的浏览器都符合: 1em=16px。那么12px=0.75em, 10px=0.625em
49、什么叫优雅降级和渐进增强?
渐进增强 progressive enhancement:
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级 graceful degradation:
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
区别:
a. 优雅降级是从复杂的现状开始,并试图减少用户体验的供给
b. 渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要
c. 降级(功能衰减)意味着往回看;而渐进增强则意味着朝前看,同时保证其根基处于安全地带
50、浏览器的内核分别是什么?
IE: trident内核
Firefox:gecko内核
Safari:webkit内核
Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核
Chrome:Blink(基于webkit,Google与Opera Software共同开发)
51、如何消除一个数组里面重复的元素?
// 方法一:
var arr1 =[1,2,2,2,3,3,3,4,5,6],
arr2 = [];
for(var i = 0,len = arr1.length; i< len; i++){
if(arr2.indexOf(arr1[i]) < 0){
arr2.push(arr1[i]);
}
}
document.write(arr2); // 1,2,3,4,5,6
52、Node. js的使用场景是什么?
高并发、实时聊天、实时消息推送、客户端逻辑强大的SPA(单页面应用程序)。
53、为什么要用 Node. js?
原因如下。
(1)简单, Node. js用 JavaScript、JSON进行编码,简单好学。
(2)功能强大,非阻塞式I/O,在较慢的网络环境中,可以分块传输数据,事件驱动,擅长高并发访问。
(3)轻量级, Node. js本身既是代码又是服务器,前后端使用同一语言。
(4)可扩展,可以轻松应对多实例、多服务器架构,同时有海量的第三方应用组件。
54、Node. js有哪些全局对象?
global、 process, console、 module和 exports。
55、process有哪些常用方法?
process.stdin process.stdout、 process.stderr、process.on、 process.env、 process.argv、 process.arch、process.platform、 process.exit
56、console有哪些常用方法?
console.log/console. info、console.error/console.warning、console.time/console.timeEnd 、console.trace、console .table。
57、Node.js有哪些定时功能?
setTimeout/clearTimeout,setInterval/clearInterval、 setImmediate/clearImmediate、 process. nextTick。
58、Node. js中的事件循环是什么样的?
事件循环其实就是一个事件队列,先加入先执行,执行完一次队列,再次循环遍历看有没有新事件加入队列。
执行中的事件叫IO事件, setlmmediate在当前队列中立即执行,setTimout/setInterval把执行定时到下一个队列, process. nextTick在当前队列执行完,下次遍历前执行。所以总体顺序是:IO事件→ setImmediate→ setTimeout/setInterval→ process. nextTick。
59、如何应用 Node. js中的 Buffer?
Buffer是用来处理二进制数据的,比如图片、MP3、数据库文件等。Buffer支持各种编码解码、二进制字符串互转。
60、Node. js中的异步和同步如何理解?
Node.js是单线程的,异步是通过一次次的循环事件队列来实现的。同步则是阻塞式的IO,这在高并发环境中会是一个很大的性能问题,所以同步一般只在基础框架启动时使用,用来加载配置文件、初始化程序等。
61、通过哪些方法可以进行异步流程的控制?
通过以下方法可以进行异步流程的控制。
(1)多层嵌套回调。
(2)为每一个回调写单独的函数,函数里边再回调。
(3)用第三方框架,如 async、q、 promise等。
62、通过哪些常用方法可以防止程序崩溃?
通过以下方法可以防止程序崩溃。
(1) try-catch-finally。
(2) EventEmitter/Stream error事件处理。
(3) domain统一控制。
(4) jshint静态检查。
(5) jasmine/mocha单元测试。
63、怎样调试 Node. js程序?
用node-- debug app. js和 node-inspector。
64 : 列出React的一些主要优点?
它提高了应用程序的性能
它可以方便地用于客户端和服务器端
由于使用JSX,使得代码的可读性增加
React 很容易与 Meteor、Angular 等其他框架集成
使用 React,编写 UI 测试用例变得极其简单
65:React 的局限性是什么?
React 只是一个库,而不是一个成熟的框架
它的库非常大,所以需要时间来理解
新手程序员理解起来可能有点困难
编码变得复杂,因为它使用内联模板和 JSX
66:什么是JSX?
JSX 是 JavaScript XML 的简写。这是 React 使用的一种文件类型,它利用了 JavaScript 的表现力以及类似 HTML 的模板语法。使得 HTML 文件非常容易理解。此文件使应用程序变得更强大并提高其性能。
下面是一个 JSX 的例子
rener(){
return(
Hello World from Edureka!!
);
}
67:如何理解“在React中,一切都是组件”?
组件是 React 应用程序 UI 的构建块。这些组件将整个 UI 拆分为独立且可重用的小块。然后它呈现这些组件中的每一个,而不会影响 UI 的其余部分。
68:React 中 render() 的目的是什么?
每个 React 组件都必须有一个 render()。它返回一个 React 元素,它是原生 DOM 组件的表示方式。如果需要渲染多个 HTML 元素,则必须将它们组合在一个封闭标签中,例如 、、
等。此函数必须保持纯洁,即每次调用时必须返回相同的结果 。
69:如何将两个或多个组件嵌入到一个中?
class MyComponent extends React.Component{
render(){
return(
<div>
<h1>Hello</h1>
<Header/>
</div>
);
}
}
class Header extends React.Component{
render(){
return
<h1>Header Component</h1>
};
}
ReactDOM.render(
<MyComponent/>, document.getElementById('content')
);
70:什么是Props?
Props 是 React 中 Properties 的简写。它们是只读组件,必须保持纯净,即不可变。在整个应用程序中,它们总是从父组件传递给子组件。子组件永远不能将 prop 发送回父组件。这有助于维护单向数据流,通常用于呈现动态生成的数据。
71:React 中的state是什么,它是如何使用的?
state状态是 React 组件的核心。状态是数据的来源,必须尽可能简单。基本上,状态是决定组件渲染和行为的对象。与 props 不同,它们是可变的,并创建动态和交互式组件。它们通过 this.state() 访问。
动态地:在这种情况下,变量可以容纳多种类型;就像在JS中,变量可以采用数字,字符。
静态地:在这种情况下,变量只能容纳一种类型,就像在Java中声明为string的变量只能接受一组字符,而不能执行其他任何操作。
72解释React组件的生命周期方法
componentWillMount () – 在客户端和服务器端渲染之前执行。
componentDidMount () – 仅在第一次渲染后在客户端执行。
componentWillReceiveProps () – 一旦从父类接收到props并且在调用另一个渲染之前调用。
shouldComponentUpdate () – 根据特定条件返回 true 或 false 值。如果你希望组件更新,请返回true否则返回false。默认情况下,它返回 false。
componentWillUpdate () – 在 DOM 中进行渲染之前调用。
componentDidUpdate () – 在渲染发生后立即调用。
componentWillUnmount () – 在组件从 DOM 中卸载后调用。它用于清理内存空间。
73:React中的事件是什么?
在 React 中,事件是对鼠标悬停、鼠标单击、按键等特定操作的触发反应。处理这些事件类似于处理 DOM 元素中的事件。但是有一些语法差异,例如:
1、 事件使用驼峰命名,而不是仅使用小写。
2、 事件作为函数而不是字符串传递。
3、 event 参数包含一组特定于事件的属性。每个事件类型都包含自己的属性和行为,只能通过其事件处理程序访问。
74:如何在React中创建事件?
class Display extends React.Component({
show(evt) {
// code
},
render() {
// Render the div with an onClick prop (value is a function)
return (
Click Me!
);
}
});
75:React中的合成事件是什么?
合成事件是充当浏览器本地事件的跨浏览器包装器的对象。它们将不同浏览器的行为组合成一个 API。这样做是为了确保事件在不同浏览器中显示一致的属性。
76:如何理解React中的refs的?
Refs 是 React 中 References 的简写。它是一个有助于存储对特定 React 元素或组件的引用的属性,该引用将由组件渲染配置函数返回。它用于返回对 render() 返回的特定元素或组件的引用。当我们需要 DOM 测量或向组件添加方法时,它们会派上用场。
class ReferenceDemo extends React.Component{
display() {
const name = this.inputDemo.value;
document.getElementById('disp').innerHTML = name;
}
render() {
return(
<div>
name: <input type="text" ref={input => this.inputDemo = input} />
<button name="Click" onClick={this.display}>Click</button>
<h2>Hello <span id="disp"></span> !!!</h2>
</div>
);
}
}
77:列出一些应该使用 Refs 的情况
当你需要管理focus,选择文本或媒体播放
触发命令式动画
与第三方 DOM 库集成
78:如何在 React 中模块化代码?
我们可以通过使用导出和导入属性来模块化代码。它们有助于在不同的文件中分别编写组件。
//ChildComponent.jsx
export default class ChildComponent extends React.Component {
render() {
return(
<div>
<h1>This is a child component</h1>
</div>
);
}
}
//ParentComponent.jsx
import ChildComponent from './childcomponent.js';
class ParentComponent extends React.Component {
render() {
return(
<div>
<App />
</div>
);
}
}
79:React 中的表单是如何创建的?
React 表单类似于 HTML 表单。但是在 React 中,状态包含在组件的 state 属性中,并且只能通过 setState() 更新。因此元素不能直接更新它们的状态,它们的提交是由 JavaScript 函数处理的。此功能可以完全访问用户在表单中输入的数据。
例如-
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name<input type="text" value={this.state.value} onChange= {this.handleSubmit} />
</label>
<input type="submit" value="Submit" />
</form
);
}
80:普通函数和箭头函数的区别
箭头函数是匿名函数,不能作为构造函数,不能使用new。箭头函数不绑定arguments,取而代之的是用rest参数…解决 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值。箭头函数通过call()或apply()方法调用一个函数时,只传入了一个参数,对this并没有影响。普通函数(谁调用我,我的this就指向谁)
81.svn和git
82.页面优化
懒加载、减少http请求、keep alive
83:深拷贝和浅拷贝 浅拷贝拷贝的是地址值,
深拷贝:JSON.parse(JSON.stringify(obj)) Object.create(obj)
84!important和max-width
width:100px!Important; max-width:80px; 最后宽度为80px
85.移动端调试、兼容
86.小程序
87什么是跨域?
跨越指的是在js中由于浏览器的同源策略限制一个网站不能访问另外一个网站的脚本,同源策略本质上是浏览器的安全策略
88如何跨域?
1、jsonp跨域
2、反向代理跨域
3、core(跨域资源共享)
88什么是pormise
定义:promise是es6新增的语法作用是用来解决层层嵌套的回调函数
promise是一个构造函数通过new关键字来创建
promise函数有三种状态:进行时(padding)成功后(resolved)失败后(rejected)
89js中如何实现继承
可以使用es6新增的class
原型继承
一个简单的原型继承functionFather(){this.age=18;}functionSon(){this.name=“zs”}Son.prototype=newFather();vars=newSon();console.log(s.age)
91:vue中v-if和v-show有什么区别
首v-if和v-show都能用于对指定元素的显示和隐藏操作但是他们在实现的方法上略有不同
v-if是通过对dom的销毁和重建来实现元素的显示和隐藏
v-show则是通过修改元素的display属性来达到显示和隐藏
5、js判断类型
92、typeof
检测不出null 和 数组,结果都为object,所以typeof常用于检测基本类型
2、instanceof
不能检测出number、boolean、string、undefined、null、symbol类型,所以instancof常用于检测复杂类型以及级成关系
3、constructor
null、undefined没有construstor方法,因此constructor不能判断undefined和null。
但是contructor的指向是可以被改变,所以不安全
4、Object.prototype.toString.call
93栈和堆的区别
1、堆
动态分配内存,内存大小不一,也不会自动释放
2、栈
自动分配相对固定大小的内存空间,并由系统自动释放
3、基本类型都是存储在栈中,每种类型的数据占用的空间的大小是确定的,并由系统自动分配和释放。内存可以及时回收。
4、引用类型的数据都是存储在堆中。准确说是栈中会存储这些数据的地址指针,并指向堆中的具体数据。
94undefined 和 null 区别
1、null
什么都没有,表示一个空对象引用(主动释放一个变量引用的兑现那个,表示一个变量不再指向任何引用地址)
2、undefined
没有设置值的变量,会自动赋值undefined
3、区别
typeof undefined // undefined
typeof null // object
null === undefined // false
null == undefined // true
95:eval()的作用
eval(string) 函数计算 JavaScript 字符串,并把它作为脚本代码来执行
如果参数是一个表达式,eval() 函数将执行表达式;
如果参数是Javascript语句,eval()将执行 Javascript 语句;
如果执行结果是一个值就返回,不是就返回undefined,如果参数不是一个字符串,则直接返回该参数。
特殊:eval(“{b:2}”) // 声明一个对象
eval(“({b:2})”) // 返回对象{b:2}
96谈谈垃圾回收机制方式及内存管理
JavaScript 在定义变量时就完成了内存分配。当不在使用变量了就会被回收,因为其开销比较大,垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。
(1)垃圾回收
标记清除法
当变量进入环境时,将这个变量标记为’进入环境’。当标记离开环境时,标记为‘离开环境’。离开环境的变量会被回收
引用技计数法
跟踪记录每个值被引用的次数,如果没有被引用,就会回收
(2)内存管理
内存分配=》内存使用=》内存回收
97请解释一下JavaScript的同源策略
同源指协议,域名,端口相同,
同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性。
98new操作符到底到了什么
(1)var obj = new Fun() 做了三件事
var obj = {} // 创建一个空对象
obj.proto = Fun.prototype //空对象的__proto__指向构造函数的原型对象
Fun.call(obj) // 构造函数this指向替换成obj
(2)实现一个new
function _new(fn, …arg) {
const obj = Object.create(fn.prototype);
const ret = fn.apply(obj, arg);
// 根据规范,返回 null 和 undefined 不处理,依然返回obj,不能使用
// typeof result === 'object' ? result : obj
return ret instanceof Object ? ret : obj;
}
99Promise和setTimeout执行先后的区别
Promise是微任务,setTimeout是宏任务,先执行微任务,如有还有微任务执行完微任务再执行下一个宏任务
100前端优化:
1、降低请求量:合并资源,减少HTTP请求数,minify/gzip压缩
2、加快请求速度:预解析DNS,减少域名数,并行加载
3、缓存:HTTP协议缓存请求,离线缓存manifest,离线数据缓存localStorage