前端常见面试题

前端常见面试题

1、 响应式布局如何实现 响应式布局可以让网站同时适配不同分辨率和不同的手机端,让客户有更好 的体验。方案一:百分比布局 利用对属性设置百分比来适配不同屏幕,注意这里的百分比是相对于父元素; 能够设置的属性有 width、height、padding、margin,其他属性比如 border、 font-size 不能用百分比设置的,先看一个简单例子: 顶部是利用设置图片 width: 50%来适应不同的分辨率,由于原始图片高度 不同,所以第一张图片顶部会有空白,这种情况最好两张图片宽高保持一致,如 果使用强制高度统一,会导致图片变形; 注意:当屏幕大于图片的宽度时,会进行拉伸;解决拉伸方法就是改为 max-width: 50%,但当屏幕大于图片的宽度时,两边会有空白。 栏目是利用设置单栏目 width: 25%来适应不同的分辨率。 由于没办法对 font-size 进行百分比设置,所以用的最多就是对图片和大块 布局进行百分比设置。 方案二:使用媒体查询 (CSS3 @media 查询)
利用媒体查询设置不同分辨率下的 css 样式,来适配不同屏幕,先看一个简 单例子:三个不同分辨率下显示对应的背景色。 媒体查询相对于百分比布局,可以对布局进行更细致的调整,但需要在每个 分辨率下面都写一套 css 样式;分辨率拆分可视项目具体情况而定。 注意:IE6、7、8 不支持媒体查询。 方案三.rem 响应式布局 当前页面中元素的 rem 单位的样式值都是针对于 html 元素的 font-size 的值 进行动态计算的,所以有两种方法可以达到适配不同屏幕: 第一种利用媒体查询,在不同分辨率下给 html 的 font-size 赋值。 第二种利用 js 动态计算赋值,详细代码如下图: 缺点就是打开页面时候,元素大小会有一个变化过程。 方案四.vw 响应式布局 根据 PSD 文件宽度或高度作为标准,元素单位 px 转换为 vw 或 vh,比如 font-size: 12px,PSD 文件宽度 375,转换公式 12 * 100 / 375,则样式改为 font-size: 3.2vw,下面是我经常使用的工具,有利于ᨀ高转换效率。
现阶段手机端用的最多就是这个方法,能保持不同屏幕下元素显示效果一致, 也不用写多套样式。 方案五.flex 弹性布局 利用 flex 属性来适配不同屏幕,下图利用简单的属性实现栏目响应式 2、 rem 布局原理 rem:相对于根元素(即 html 元素)font-size 计算值的倍数。 通俗的说,1rem = html 的 font-size 值 这段代码。a 标签的 font-size 值为 0.5rem,实际就是 100px*0.5=50px。 html{font-size:100px;} a{font-size:.5rem;} 如何使用 rem 进行布局? 1. 标签的 rem 单位的值怎么计算 通过使用 rem + js 改变 html 标签的 font-size(整体缩放)实现兼容性更高的页面 下面来举个例子, 当我们拿到的设计图是 750px 的时候,窗口宽度 750px,html 的 font-size 的大小为 100px;也就是说 1rem = 100px;所以标题的 font-size 的大小为 26/100=.26rem; 2. 如何实现兼容各种屏幕大小的设备
使用到 javascript 来动态改变 html 标签 font-size 的大小,其他的 rem 单位的数值就会 被浏览动态计算转为 px 单位,从而达到和设计图高度的相似。 当屏幕 750px 的时候,html 的 font-size 值是 100px;窗口大小变化的时候,可以通过 js 获取到窗口大小。 这时候获取到一个比例 750:100=获取到的屏幕大小:html 标签的 px 单位的值 以下 js 代码,用于实现根据获取到的屏幕大小,动态修改 html 标签的 px 单位的值
3、 三种方式实现一个 div 水平和垂直方向的居中 1. 2. 3. 4、 数据类型判断 1. typeof typeof 对于基本数据类型判断是没有问题的,但是遇到引用 数据类型(如:Array)是不起作用 2. instanceof 判断 new 关键字创建的引用数据类型 不考虑 null 和 undefined(这两个比较特殊)以对象字面量创建的基 本数据类型
3. constructor constructor 似乎完全可以应对基本数据类型和引用数据 类型 但如果声明了一个构造函数,并且把他的原型指向了 Array 的原 型,所以这种情况下,constructor 也显得力不从心 4. Object.prototype.toString.call() 完美的解决方案 5、 Arguments arguments 是一个类似数组的对象, 对应于传递给函数的参数。 1. ᧿述arguments 对象是所有函数中可用的局部变量。你可以使用 arguments 对 象在函数中引用函数的参数。 2. 属性 x arguments.callee 指向当前执行的函数。 x arguments.caller **指向调用当前函数的函数。 x arguments.length 指向传递给当前函数的参数数量。 3. 例子 定义一个连接几个字符串的函数 function myConcat(separator) { var args = Array.prototype.slice.call(arguments, 1); return args.join(separator); }剩余参数, 默认参数 和 解构赋值参数 function foo(…args) { return args; }foo(1, 2, 3); // [1,2,3] 等 6、 原型和原型链 1、原型的概念 JavaScript 的所有对象中都包含了一个 [proto] 内部属性,这个属性所对应 的就是自身的原型 JavaScript 的函数对象,除了原型 [proto] 之外,还有 prototype 属性,当 函数对象作为构造函数创建实例时,该 prototype 属性值将被作为实例对象的
原型 [proto] 2、原型链的概念 当一个对象调用自身不存在的属性/方法时,就会去自己 [proto] 关联的前 辈 prototype 对象上去找,如果没找到,就会去该 prototype 原型 [proto] 关 联的前辈 prototype 去找。依次类推,直到找到属性/方法或 undefined 为止。 从而形成了所谓的“原型链”。 3、总结JavaScript 中的对象,都有一个内置属性[Prototype],指向这个对象的原型 对象。当查找一个属性或方法时,如果在当前对象中找不到,会继续在当前对象 的原型对象中查找;如果原型对象中依然没有找到,会继续在原型对象的原型中 查找(原型也是对象,也有它自己的原型);直到找到为止,或者查找到最顶层 的原型对象中也没有找到,就结束查找,返回 undefined。这个查找过程是一个 链式的查找,每个对象都有一个到它自身原型对象的链接,这些链接组建的整个 链条就是原型链。拥有相同原型的多个对象,他们的共同特征正是通过这种查找 模式体现出来的。 在上面的查找过程,我们ᨀ到了最顶层的原型对象,这个对象就是 Object.prototype,这个对象中保存了最常用的方法,如 toString、valueOf、 hasOwnProperty 等,因此我们才能在任何对象中使用这些方法。 7、 闭包 闭包:定义 当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了 其父函数的内部变量,且返回的那个函数在外部被执行,就产生了闭包. 闭包是一个环境,具体指的就是外部函数–高阶函数 closure 闭包的三个特性 1:函数套函数 2:内部函数可以直接访问外部函数的内部变量或参数 3:变量或参数不会被垃圾回收机制回收 GC 闭包的优点: 1:变量长期驻扎在内存中 2:避免全局变量的污染
3:私有成员的存在 闭包的缺点 常驻内存 增大内存的使用量 使用不当会造成内存的泄露. 闭包的两种写法: 1: function a () { var num=1; function b () { alert(num) }return b;//把函数 b 返回给函数 a; }alert(a())//弹出函数 a, 值是函数 b; 2: function a () { var num=1; return function b () {//把函数 b 返回给函数 a; alert(num=num+2) } }alert(a())//弹出函数 a, 值是函数 b; 调用方式://1:直接调用 a()()//内部函数的执行 //2:通过赋值在调用 var f = a(); f()

8、 js 继承 ES5 有 6 种方式可以实现继承,分别为: 1. 原型链继承 原型链继承的基本思想是利用原型让一个引用类型继承另一个引用 类型的属性和方法。 缺点:1 通过原型来实现继承时,原型会变成另一个类型的实例,原先的 实例属性变成了现在的原型属性,该原型的引用类型属性会被所 有的实例共享。 2 在创建子类型的实例时,没有办法在不影响所有对象实例的情况 下给超类型的构造函数中传递参数。 2. 借用构造函数 借用构造函数的技术,其基本思想为: 在子类型的构造函数中调用超类型构造函数。 优点: 1 可以向超类传递参数 2 解决了原型中包含引用类型值被所有实例共享的问题
缺点: • 方法都在构造函数中定义,函数复用无从谈起,另外超类型原型 中定义的方法对于子类型而言都是不可见的。 3. 组合继承(原型链 + 借用构造函数) 组合继承指的是将原型链和借用构造函数技术组合到一块,从而发挥 二者之长的一种继承模式。基本思路: 使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现 对实例属性的继承,既通过在原型上定义方法来实现了函数复用,又保证 了每个实例都有自己的属性。 缺点: • 无论什么情况下,都会调用两次超类型构造函数:一次是在创建 子类型原型的时候,另一次是在子类型构造函数内部。 优点: • 可以向超类传递参数 • 每个实例都有自己的属性 • 实现了函数复用 4. 原型式继承 原型继承的基本思想: 借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定 义类型。
在 object() 函数内部,先穿甲一个临时性的构造函数,然后将传入 的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例, 从本质上讲,object() 对传入的对象执行了一次浅拷贝。 ECMAScript5 通过新增 Object.create()方法规范了原型式继承。这个 方法接收两个参数:一个用作新对象原型的对象和(可选的)一个为新对 象定义额外属性的对象(可以覆盖原型对象上的同名属性),在传入一个参 数的情况下,Object.create() 和 object() 方法的行为相同。 在没有必要创建构造函数,仅让一个对象与另一个对象保持相似的情 况下,原型式继承是可以胜任的。 缺点: 同原型链实现继承一样,包含引用类型值的属性会被所有实例共享。 5. 寄生式继承 寄生式继承是与原型式继承紧密相关的一种思路。寄生式继承的思路 与寄生构造函数和工厂模式类似,即创建一个仅用于封装继承过程的函数, 该函数在内部已某种方式来增强对象,最后再像真地是它做了所有工作一 样返回对象。
基于 person 返回了一个新对象 -—— person2,新对象不仅具有 person 的所有属性和方法,而且还有自己的 sayHi() 方法。在考虑对象 而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。 缺点:• 使用寄生式继承来为对象添加函数,会由于不能做到函数复用而 效率低下。 • 同原型链实现继承一样,包含引用类型值的属性会被所有实例共 享。 6. 寄生组合式继承 所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链 的混成形式来继承方法,基本思路: 不必为了指定子类型的原型而调用超类型的构造函数,我们需要的仅 是超类型原型的一个副本,本质上就是使用寄生式继承来继承超类型的原 型,然后再将结果指定给子类型的原型。寄生组合式继承的基本模式如下 所示:• 第一步:创建超类型原型的一个副本 • 第二步:为创建的副本添加 constructor 属性 • 第三步:将新创建的对象赋值给子类型的原型 至此,我们就可以通过调用 inheritPrototype 来替换为子类型原型 赋值的语句: 优点: 只调用了一次超类构造函数,效率更高。避免在 SuberType.prototype
上面创建不必要的、多余的属性,与其同时,原型链还能保持不变。 因此寄生组合继承是引用类型最理性的继承范式。 ES6 实现继承 9、 什么是深拷贝,浅拷贝,如何实现 深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而 深拷贝是层层拷贝。 深拷贝 深拷贝复制变量值,对于非基本类型的变量,则递归至基本类型变 量后,再复制。 深拷贝后的对象与原来的对象是完全隔离的,互不影响, 对一个对象的修改并不会影响另一个对象。 浅拷贝 浅拷贝是会将对象的每个属性进行依次复制,但是当对象的属性值 是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化。 可 以 使 用 for in 、 Object.assign 、 扩 展 运 算 符 … 、 Array.prototype.slice()、Array.prototype.concat() 、递归等递归函数实现深 拷贝

10、 事件冒泡,事件捕获 什么是事件? 事件是文档和浏览器窗口中发生的特定的交互瞬间。 事件是 javascript 应 用跳动的心脏,也是把所有东西黏在一起的胶水,当我们与浏览器中 web 页面 进行某些类型的交互时,事件就发生了。 事件可能是用户在某些内容上的点击,鼠标经过某个特定元素或按下键盘 上的某些按键,事件还可能是 web 浏览器中发生的事情,比如说某个 web 页面 加载完成,或者是用户滚动窗口或改变窗口大小。 什么是事件流? 事件流᧿述的是从页面中接受事件的顺序,但有意思的是,微软(IE)和 网景(Netscape)开发团队居然ᨀ出了两个截然相反的事件流概念,IE 的事件流 是事件冒泡流(event bubbling),而 Netscape 的事件流是事件捕获流(event capturing)。
事件冒泡和事件捕获的概念: 事件冒泡和事件捕获是᧿述事件触发事件时序问题的术语,事件捕获指的是 从 document 到触发事件的那个节点,也就是说自上而下的去触发事件,相反的, 事件冒泡是自下而上的去触发事件,绑定事件方法的第三个参数,就是控制事件 触发顺序是否为事件捕获,true 为事件捕获,false 为事件冒泡,jQuery 的 e.stopPropagation 会阻止冒泡,意思就是到我为止,我的爹和祖宗的事件就不要 触发了。 第一种:事件冒泡 IE ᨀ出的事件流叫做事件冒泡,即事件开始时由最具体的元素接收,然后 逐级向上传播到较为不具体的节点 执行顺序: p=>button=>div=>body 正如上面我们所说的,它会从一个最具体的的元素接收,然后逐级向上传播, p=>button=>div=>body…事件冒泡可以形象地比喻为把一颗石头投入水中, 泡泡会一直从水底冒出水面,也就是说从小到大开始传播。 第二种:事件捕获 网景公司ᨀ出的事件流叫事件捕获流。 事件捕获流的思想是不太具体的 DOM 节点应该更早接收到事件,而最具体 的节点应该最后接收到事件,针对上面同样的例子,点击按钮,那么此时 click 事件会按照这样传播:(下面我们就借用 addEventListener 的第三个参数来模拟 事件捕获流),也就是上面的例子就会倒过来。
正如我们看到的,和冒泡流万全相反,从最不具体的元素接收到最具体的元 素接收事件 body=>div=>button=>p 11、 h5 和 css3 的新特性 h5 每个人有每个人的理解,我的理解呢!我的理解是 h5 呢并不是新增一些标 签和样式更多的是里面新增的一些功能例如重力感应,他可以让我们感知当前手 机的状态,可以帮助我们完成手机摇一摇,监听当前我们步数,还有开启 3d 模 式让我们的 2d 空间变成一个 3d 模式,而且 h5 中为了挺高页面性能,页面元素的 变大,不在是元素本身的大小变化,而是一种视觉上的效果,从而减少了 dom 操作,防止了页面的重绘,当然 h5 中不单单是这些还有 webgl 游戏引擎 canvas、 svg 完成图表以及一些小游戏的开发例如大转盘,数钱游戏,jd 妈妈再打我一次 等等! 12、 http/https/http2.0 HTTP 是一种协议,也是一种请求,只要是你调用接口的,或是你发送请求 的时候都是发送一种 HTTP 请求,然后我们常用的那种 HTTP 请求的话,比如说 GET 啊,POST 啊,这种这种请求的话,其实,只要是你发送一次请求,它是两 个都是存在的,GET、POST 的是同时存在的。然后 GET 的话在 HTTP 的头上, POST 在那身体里面。的话,然后因为在头部的话,所以说它传输量比较小一点, 一般来说是 32k,POST 在身体上比较大一点,大约是 2G,而且 post 的话能够传 输所有的二进制文件和数据,GET 只能接受数据,GET 这种请求因为在地址栏上所
以它更不安全,post 这种因为在身体上所以它相对安全,GET 是有缓存,POST 是没有缓存,但是 GET 请求一直存在,主要原因还是 GET 这种请求的话,可以做分 享和收藏,美丽说,蘑菇街都是通过分享和收藏火起来,并且发展起来,所以 GET 的作用不可小觑,这个就是我理解的 http 请求,而且 http 请求的话是一种无 状态的请求所以,我们会用 session 或是 token 去记录它当前的状态,或是他当 前的权限,比如只有你登录以后你才可以获取到他的数据,https 这种请求是对 http 请求的再次封装以后的结果,接下来我就说一说他与 http 请求的区别 https 协议需要到 ca 申请证书,一般免费证书较少,因而需要一定费用,这是第一点, 第二点就是 http 这种请求是明文传输,https 则是具有安全性的 ssl 加密传输协 议,第三点 http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前 者是 80,后者是 443 最后一点就是 http 的连接很简单,是无状态的,HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全 13、 Axios 拦截做过哪些 Axios 拦截分为请求拦截和响应拦截,请求拦截就是在你请求的时候会进行 触发!只要是你发送一个 axios 请求就会触发!所以我们主要用它做我们的 loading 加载和数据的权限验证,包括我们所有的数据预加载也可以实现,响应拦 截主要是我们在 loading 加载,和做所有数据加载需要整体的结束,这个时候的 结束就需要在数据马上发给前端的时候进行隐藏和结束,包括我们的请求头的设 置,后端数据已经发送过来的时候,我们为了确保请求头的传递就必须在看看 header 里面是否有你需要的请求,如果有的话,再次进行设置!当然用 axios 拦截也可以配置公用地址,以及对于跨域问题解决,这个就是用 axios 拦截实现 的功能。 14、 sessionStoragelocalStorage cookie 的区别 1.localStorage 生命周期是永久,这意味着除非用户显示在浏览器ᨀ供的 UI 上清除 localStorage 信息,否则这些信息将永远存在。存放数据大小为一般为 5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。 2.sessionStorage 仅在当前会话下有效,关闭页面或浏览器后被清除。存放 数据大小为一般为 5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务 器的通信。源生接口可以接受,亦可再次封装来对 Object 和 Array 有更好的支 持。
作用域不同 不同浏览器无法共享 localStorage 或 sessionStorage 中的信息。相同浏览器 的不同页面间可以共享相同的 localStorage(页面属于相同域名和端口),但是 不同页面或标签页间无法共享 sessionStorage 的信息。这里需要注意的是,页面 及标3. cookie 的优点:具有极高的扩展性和可用性 1.通过良好的编程,控制保存在 cookie 中的 session 对象的大小。 2.通过加密和安全传输技术,减少 cookie 被破解的可能性。 3.只有在 cookie 中存放不敏感的数据,即使被盗取也不会有很大的损失。 4.控制 cookie 的生命期,使之不会永远有效。这样的话偷盗者很可能拿到的 就是一个过期的 cookie。 4. cookie 的缺点: 1.cookie 的长度和数量的限制。每个 domain 最多只能有 20 条 cookie,每个 cookie 长度不能超过 4KB。否则会被截掉。 2.安全性问题。如果 cookie 被人拦掉了,那个人就可以获取到所有 session 信息。加密的话也不起什么作用。 3.有些状态不可能保存在客户端。例如,为了防止重复ᨀ交表单,我们需要 在服务端保存一个计数器。若吧计数器保存在客户端,则起不到什么作用。 localStorage、sessionStorage、Cookie 共同点:都是保存在浏览器端,且同 源的。 15、 图片懒加载实现原理 一.什么是懒加载? 懒加载突出一个“懒”字,懒就是拖延迟的意思,所以“懒加载”说白了就是 延迟加载,比如我们加载一个页面,这个页面很长很长,长到我们的浏览器可 视区域装不下,那么懒加载就是优先加载可视区域的内容,其他部分等进入了 可视区域在加载。 二.为什么要懒加载? 懒加载是一种网页性能优化的方式,它能极大的ᨀ升用户体验。就比如说 图片,图片一直是影响网页性能的主要元凶,现在一张图片超过几兆已经是很 经常的事了。如果每次进入页面就请求所有的图片资源,那么可能等图片加载
出来用户也早就走了。所以,我们需要懒加载,进入页面的时候,只请求可视 区域的图片资源。 总结出来就两个点: 1.全部加载的话会影响用户体验 2.浪费用户的流量,有些用户并不像全部看完,全部加载会耗费大量流量。 三.懒加载的实现原理? 由于网页中占用资源较多的一般是图片,所以我们一般实施懒加载都是对图 片资源而言的,所以这里的实现原理主要是针对图片。 大家都知道,一张图片就是一个标签,而图片的来源主要是 src 属性。 浏览器是否发起亲求就是根据是否有 src 属性决定的。 既然这样,那么我们就要对标签的 src 属性下手了,在没进入可视区 域的时候,我们先不给这个标签赋 src 属性,这样岂不是浏览器就不会发 送请求了。 16、 瀑布流原理 瀑布流又称瀑布流式布局,是比较流行的一种网站页面布局方式 视觉表现为参差不齐的多栏布局,最早采用此布局的是网站是 Pinterest, 后逐渐在国内流行即多行等宽元素排列,后面的元素依次添加到其后,等宽不等 高,根据图片原比例缩放直至宽度达到我们的要求,依次按照规则放入指定位置。 下面通过图解来分析一下瀑布流的算法。 当第一排排满足够多的等宽图片时(如下图情况),自然而然的考虑到之后
放置的图片会往下面排放。 那么第六张图片,放置在什么位置呢?是下图的位置么? 我们通过瀑布流算法实验得到,后面紧跟的第六张图片的位置应该是这个位置。 因为放置它之前,这一列的高度为所有列中最小,所以会放置在这个地方。 所以我们知道了,如果再继续放置下去,第七张图片应该是这个位置 通过瀑布流算法实验得出位置正确。 看懂这个图示应该就能理解了瀑布流的原理算法。
总结瀑布流布局原理: 瀑布流的实现原理就是通过比较每一列的高度,如果这一列高度低的话就在 这一列进行添加,如果可视区距离和滚动距离想加的话比你当前页面的高度还要 高的时候,页面就开再次加载多个,这个主要也是页面布局,如果你的布局实现 的不好的话!也会出现问题,首先每一列的高度,都是需要自适应的,不能设置 高通过每一块内容将每一列撑起来,还有一个问题就是,滑动底部,根据每个电 脑的不同,所以他每个人,获取的高度是不同而且有的时候,页面的整体高度和 页面可视区高度加上滚动高度差 1px 这个时候就需要我们ᨀ前加载,不然滑动 到底部也加载不出来! 17、 Call、 apply 区别,原生实现 bind Call、apply、bind 都是改变 this 指向的,其中 call 的话是通过第一个参数 来改变 this 指向,函数在传参的时候一个一个进行传参,apply 也是通过第一个 参数改变 this 指向,函数传参的时候通过数组或是一组的形式进行传参,而且 他只能用于函数的调用时候,而 bind 呢不能用于函数的标准调用传参,只能是 事件或是方法的后边进行改变 this 的指向 18、 解构赋值 ES6 允许按照一定模式,从数组和对象中ᨀ取值,对变量进行赋值,这被称 为解构(Destructuring) 解构赋值,左右结构必须一样,使用左边定义的值,快速的取出数据中对应 的数据值,而且 定义和赋值必须放到一起,不然的话就会报错,取不出来数据 值,而且左边也必须是一个 js 存在数据结构不然的话也会报错,解构赋值的主 要作用还是,快速的让我们在数据中抓取出我们想要的数据。
19、 let、const let 是在定义变量,不能重复定义,但是在不同的作用域里面就可以进行再 次定义,let 这种定义可以再次修改定义的数据值,let 有自己的作用域,只要是 有花括号就在一个作用域,利用这个特性也可以解决循环里面加事件,事件里面 的 i 值不能用的问题!let 主要在于方法和事件里面的可以修改的变量的定义, const 是定义一个常量,也是不能重复定义,只要是有一个花括号就有一个作用 域,不能修改,但是这些只要是在不同的作用域中就可以 20、 async/await Async 和 await 是一种同步的写法,但还是异步的操作,两个内容还是必须 同时去写才会生效不然的话也是不会好使,而且 await 的话有一个不错的作用就 是可以等到你的数据加载过来以后才会去运行下边的 js 内容,而且 await 接收的 对象必须还是个 promise 对象,如果是接收数据的时候就可以直接用一句话来接 收数据值,所以这个 async await 我的主要应用是在数据的接收,和异步问题的 处理,主要是还是解决不同执行时机下的异步问题! 21、 es6 中函数有哪些拓展 1. 新增了块级作用域(let,const) 2. ᨀ供了定义类的语法糖(class) 3. 新增了一种基本数据类型(Symbol) 4. 新增了变量的解构赋值 5. 函数参数允许设置默认值,引入了 rest 参数,新增了箭头函数 6. 数组新增了一些 API,如 isArray / from / of 方法;数组实例新增了 entries(),keys() 和 values() 等方法 7. 对象和数组新增了扩展运算符 8. ES6 新增了模块化(import/export) 9. ES6 新增了 Set 和 Map 数据结构 10. ES6 原生ᨀ供 Proxy 构造函数,用来生成 Proxy 实例 11. ES6 新增了生成器(Generator)和遍历器(Iterator) 22、 日常前端代码开发中,有哪些值得用 ES6 去改进的编程优 化或者规范? x 常用箭头函数来取代 var self = this;的做法。
x 常用 let 取代 var 命令。 x 常用数组/对象的结构赋值来命名变量,结构更清晰,语义更明确,可读 性更好。 x 在长字符串多变量组合场合,用模板字符串来取代字符串累加,能取得更 好地效果和阅读体验。 x 用 Class 类取代传统的构造函数,来生成实例化对象。 x 在大型应用开发中,要保持 module 模块化开发思维,分清模块之间的关 系,常用 import、export 方法。 23、 请写出在 vue 中使用 promise 封装项目 api 接口的思路? axios 封装了原生的 XHR,让我们发送请求更为简单,但假设在一个成百上 千个 vue 文件的项目中,我们每一个 vue 文件都要写 axios.get()或 axios.post() 岂不是很麻烦?后期的维护也不方便,所以我们要对 axios 进行进一步的封装。 1.构赋 vue-cli 项目的目录如上,我们在原有的目录基础上新建 api 与 utils 文件夹,utils 里新建 request.js 文件,request.js 代码如下:
在 request.js 中做了三件事 1.创建 axios,设置 baseURL 与超时时间 2.拦截请求 3.拦截响应
4.路由拦截 24、 解构赋值的规则是什么以及解构赋值的用途有哪些? 规则:只要等号右边的值不是对象或数组,就先将其转为对象。 用途:1. 交换变量的值 2. 函数参数的默认值 3. ᨀ取 JSON 数据 25、 promise 是什么?有哪些状态和参数?如何使用? 1、主要用于异步计算 2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果 3、可以在对象之间传递和操作 promise,帮助我们处理队列 resolve 作用是,将 Promise 对象的状态从“未完成”变为“成功”(即 从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果, 作为参数传递出去; reject 作用是,将 Promise 对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错 误,作为参数传递出去。 promise 有三个状态: 1、pending[待定]初始状态 2、fulfilled[实现]操作成功 3、rejected[被否决]操作失败 当 promise 状态发生改变,就会触发 then()里的响应函数处理后续步骤; promise 状态一经改变,不会再变。 Promise 对象的状态改变,只有两种可能: 从 pending 变为 fulfilled 从 pending 变为 rejected。 这两种情况只要发生,状态就凝固了,不会再变了。
26、 for…in 迭代和 for…of 有什么区别 1、推荐在循环对象属性的时候,使用 for…in,在遍历数组的时候的时候使用 for…of。 2、for…in 循环出的是 key,for…of 循环出的是 value 3、注意,for…of 是 ES6 新引入的特性。修复了 ES5 引入的 for…in 的不足 4、for…of 不能循环普通的对象,需要通过和 Object.keys()搭配使用 27、 generator(异步编程、yield、next()、await 、async) ᨀ示:Generator 是一个迭代器生成函数,其返回值是一个迭代器(Iterator), 可用于异步调用。 比如某个事物只有三种状态(状态 A,状态 B,状态 C),而这三种状态的变 化是状态 A =>状态 B =>状态 C =>状态 A ,这就是状态机。Generator 特别适用 于处理这种状态机 28、 Ajax 是什么?以及如何创建 Ajax? ᨀ示:1、Ajax 并不算是一种新的技术,全称是 asychronous javascript and xml, 可以说是已有技术的组合,主要用来实现客户端与服务器端的异步通信效果,实 现页面的局部刷新,早期的浏览器并不能原生支持 ajax,可以使用隐藏帧(iframe) 方式变相实现异步效果,后来的浏览器ᨀ供了对 ajax 的原生支持 . 2、使用 ajax 原生方式发送请求主要通过 XMLHttpRequest( 标准浏览 器 ) 、 ActiveXObject(IE 浏览器)对象实现异步通信效果 . 3、基本步骤: javascript var xhr =null;//创建对象 if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{xhr = new ActiveXObject("Microsoft.XMLHTTP"); }xhr.open(“方式”,”地址”,”标志位”);//初始化请求 xhr.setRequestHeader(“”,””);//设置 http 头信息 xhr.onreadystatechange =function(){}//指定回调函数 xhr.send();//发送请求4、js 框架(jQuery/EXTJS 等)ᨀ供的 ajax API 对原生的 ajax 进行了封 装,熟悉了基础理论,再学习别的框架就会得心应手,好多都是换汤不换药的内 容29、 同步和异步的区别? 1、同步:阻塞的 - 张三叫李四去吃饭,李四一直忙得不停,张三一直等着,直到李四忙完 两个人一块去吃饭 =浏览器向服务器请求数据,服务器比较忙,浏览器一直等 着(页面白屏),直到服务器返回数据,浏览器才能显示页面 2、异步:非阻塞的 - 张三叫李四去吃饭,李四在忙,张三说了一声然后自己就去吃饭了,李 四忙完后自己去吃 =浏览器向服务器请求数据,服务器比较忙,浏览器可以自 如的干原来的事情(显示页面),服务器返回数据的时候通知浏览器一声,浏 览器把返回的数据再渲染到页面,局部更新 30、 Ajax 请求的时候 get 和 post 方式的区别? 1、理解跨域的概念:协议、域名、端口都相同才同域,否则都是跨域 2、出于安全考虑,服务器不允许 ajax 跨域获取数据,但是可以跨域获取 文件内容,所以基于这一点,可以动态创建 script 标签,使用标签的 src 属性 访问 js 文件的形式获取 js 脚本,并且这个 js 脚本中的内容是函数调用,该 函数调用的参数是服务器返回的数据,为了获取这里的参数数据,需要事先在页 面中定义回调函数,在回调函数中处理服务器返回的数据,这就是解决跨域问题 的主流解决方案 31、 解释 jsonp 的原理,以及为什么 jsonp 为什么不是真正的 ajax? 答:产生跨域的情况有:不同协议,不同域名,不同端口以及域名和 ip 地址 的访问都会产生跨域。
跨域的解决方案目前有三种主流解决方案: 是 jsonp jsonp 实现原理:主要是利用动态创建 script 标签请求后端接口地址,然后 传递 callback 参数,后端接收 callback,后端经过数据处理,返回 callback 函数 调用的形式,callback 中的参数就是 json 优点:浏览器兼容性好, 缺点:只支持 get 请求方式 是代理(前端代理和后端通常通过 nginx 实现反向代理) 前端代理我在 vue 中主要是通过 vue 脚手架中的 config 中的 index 文件来配 置的,其中有个 proxyTable 来配置跨域的 前端代理核心实现通过 http-proxy-middleware 插件来实现的,vue2.x 和 vue3.x 脚手架代理跨域实现原理是一样的 是 CORS CORS 全称叫跨域资源共享,主要是后台工程师设置后端代码来达到前端跨 域请求的CORS 的原理:CORS 定义一种跨域访问的机制,可以让 AJAX 实现跨域访问。 CORS 允许一个域上的网络应用向另一个域ᨀ交跨域 AJAX 请求。实现此功能非 常简单,只需由服务器发送一个响应标头即可。 优点:无需前端工程师设置,只需后端工程师在请求的页面中配置好,并且 支持所有请求方式(例如:get,post,put,delete 等) 缺点:浏览器支持有版本要求,如下: chrome:13+,firefox:3.5+,IE 11+,edge:12+ 注:现在主流框架都是用代理和 CORS 跨域实现的 32、 说一下从输入 URL 到页面加载完中间发生了什么? 答:大致过程是这样的: 1. DNS 解析 2. TCP 连接 3. 发送 HTTP 请求 4. 服务器处理请求并返回需要的数据 5. 浏览器解析渲染页面
6. 连接结束 注:这里会延伸出问 http 状态码,和三次握手和四次挥手相关问题: (1)http 状态码: 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码 2xx (成功) 表示成功处理了请求的状态码。 常见的 2 开头的状态码有:200 – 服务器成功返回网页 3xx (重定向) 表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定 向 常见的 3 字开头的状态码有: 301 (永久移动) 请求的网页已永久移动到新位置。 服 务器返回此响应时,会自动将请求者转到新位置。 302 (临时移动) 服务器目前从不同位置的网页响应请 求,但请求者应继续使用原有位置来进行以后的请求。 304 (未修改)自从上次请求后,请求的网页未修改过。服 务器返回此响应时,不会返回网页内容。 4xx(请求错误) 这些状态代码表示请求可能出错,妨碍了服务器的处 理。 常见的 4 字开头的状态有:404 – 请求的网页不存在 5xx(服务器错误) 这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错 误可能是服务器本身的错误,而不是请求出错。 常见的以 5 开头的状态码有: 500 (服务器内部错误) 服务器遇到错误,无法完成请 求。503 (服务不可用) 服务器目前无法使用(由于超载或停 机维护)。 通常,这只是暂时状态
(2)三次握手和四次挥手: ***三次握手: TCP 协议中,主动发起请求的一端称为『客户端』,被动连接的一端称为『服 务端』。不管是客户端还是服务端,TCP 连接建立完后都能发送和接收数据。 起初,服务器和客户端都为 CLOSED 状态。在通信开始前,双方都得创建各 自的传输控制块(TCB)。 服务器创建完 TCB 后遍进入 LISTEN 状态,此时准备接收客户端发来的连接请求。 第一次握手 客户端向服务端发送连接请求报文段。该报文段的头部中 SYN=1,ACK=0, seq=x。请求发送后,客户端便进入 SYN-SENT 状态。 x PS1:SYN=1,ACK=0 表示该报文段为连接请求报文。 x PS2:x 为本次 TCP 通信的字节流的初始序号。 TCP 规定:SYN=1 的报文段不能有数据部分,但要消耗掉一个序号。 第二次握手 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1, ACK=1,seq=y,ack=x+1。 该应答发送完成后便进入 SYN-RCVD 状态。 x PS1:SYN=1,ACK=1 表示该报文段为连接同意的应答报文。 x PS2:seq=y 表示服务端作为发送者时,发送字节流的初始序号。 x PS3:ack=x+1 表示服务端希望下一个数据报发送序号从 x+1 开始的字节。
第三次握手 当客户端收到连接同意的应答后,还要向服务端发送一个确认报文段,表示: 服务端发来的连接同意应答已经成功收到。 该报文段的头部为:ACK=1,seq=x+1,ack=y+1。 客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进 入 ESTABLISHED 状态,此时连接的建立完成! 为什么连接建立需要三次握手,而不是两次握手? 防止失效的连接请求报文段被服务端接收,从而产生错误。 ***TCP 四次挥手: TCP 连接的释放一共需要四步,因此称为『四次挥手』。 我们知道,TCP 连接是双向的,因此在四次挥手中,前两次挥手用于断开一 个方向的连接,后两次挥手用于断开另一方向的连接。 第一次挥手 若 A 认为数据发送完成,则它需要向 B 发送连接释放请求。该请求只有报文 头,头中携带的主要参数为: FIN=1,seq=u。此时,A 将进入 FIN-WAIT-1 状态。 x PS1:FIN=1 表示该报文段是一个连接释放请求。 x PS2:seq=u,u-1 是 A 向 B 发送的最后一个字节的序号。·
第二次挥手 B 收到连接释放请求后,会通知相应的应用程序,告诉它 A 向 B 这个方向的 连接已经释放。此时 B 进入 CLOSE-WAIT 状态,并向 A 发送连接释放的应答,其 报文头包含: ACK=1,seq=v,ack=u+1。 x PS1:ACK=1:除 TCP 连接请求报文段以外,TCP 通信过程中所有数据报的 ACK 都为 1,表示应答。 x PS2:seq=v,v-1 是 B 向 A 发送的最后一个字节的序号。 x PS3:ack=u+1 表示希望收到从第 u+1 个字节开始的报文段,并且已经成 功接收了前 u 个字节。 A 收到该应答,进入 FIN-WAIT-2 状态,等待 B 发送连接释放请求。 第二次挥手完成后,A 到 B 方向的连接已经释放,B 不会再接收数据,A 也不 会再发送数据。但 B 到 A 方向的连接仍然存在,B 可以继续向 A 发送数据。 第三次挥手 当 B 向 A 发完所有数据后,向 A 发送连接释放请求,请求头:FIN=1,ACK=1, seq=w,ack=u+1。B 便进入 LAST-ACK 状态。 第四次挥手 A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状 态会持续 2MSL 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态, 撤销 TCB。当 B 收到确认应答后,也便进入 CLOSED 状态,撤销 TCB。 为什么 A 要先进入 TIME-WAIT 状态,等待 2MSL 时间后才进入 CLOSED 状态? 为了保证 B 能收到 A 的确认应答。 若 A 发完确认应答后直接进入 CLOSED 状态,那么如果该应答丢失,B 等待超 时后就会重新发送连接释放请求,但此时 A 已经关闭了,不会作出任何响应,因 此 B 永远无法正常关闭。
33、 Vue 中 methods,computed, watch 的区别 1)methods 中都是封装好的函数,无论是否有变化只要触发就会执行 适用场景:组件中功能的封装,逻辑处理 2)computed:是 vue 独有的特性计算属性,可以对 data 中的依赖项再重新计 算得到一个新值,应用到视图中,和 methods 本质区别是 computed 是可缓存的, 也就是说 computed 中的依赖项没有变化,则 computed 中的值就不会重新计算, 而 methods 中的函数是没有缓存的。 适用场景:假设我们有一个性能开销比较大的计算属性 A,它需要遍历一 个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。 如果没有缓存,我们将不可避免的多次执行某个函数 3)Watch 是监听 data 和计算属性中的新旧变化 适用场景:当需要在数据变化时执行“异步”或“开销较大”的操作时,这 个方式是最有用的 34、 prop 验证,和默认值 所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件 意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。 额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最 新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 e m i t 派 发 一 个 自 定 义 事 件 , 父 组 件 接 收 到 后 , 由 父 组 件 修 改 。 有 两 种 常 见 的 试 图 改 变 一 个 p r o p 的 情 形 : ( 1 ) 这 个 用 来 传 递 一 个 初 始 值 ; 这 个 子 组 件 接 下 来 希 望 将 其 作 为 一 个 本 地 的 数 据 来 使 用 。 在 这 种 情 况 下 , 最 好 定 义 一 个 本 地 的 属 性 并 将 这 个 用 作 其 初 始 值 : ( 2 ) 这 个 以 一 种 原 始 的 值 传 入 且 需 要 进 行 转 换 。 在 这 种 情 况 下 , 最 好 使 用 这 个 的 值 来 定 义 一 个 计 算 属 性 35 、 v u e 双 向 数 据 绑 定 原 理 1 、 实 现 一 个 数 据 监 听 器 O b s e r v e r , 能 够 对 数 据 对 象 的 所 有 属 性 进 行 监 听 , 如 有 变 动 可 拿 到 最 新 值 并 通 知 订 阅 者 2 、 实 现 一 个 指 令 解 析 器 C o m p i l e , 对 每 个 元 素 节 点 的 指 令 进 行 扫 ᧿ 和 解 析 , 根 据 指 令 模 板 替 换 数 据 , 以 及 绑 定 相 应 的 更 新 函 数 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值