0


华为od前端面试题

es6新特性

  1. let、const、块级作用域;解构赋值
  2. 一些原生对象新增了方法,比如string的模板字符串;函数的默认值、箭头函数;数组的扩展运算符;对象名可以简写(key,value相同时可以只写一个)、Object.is()、Object.assign()、遍历对象:for-in、Object.keys()、Object.getOwnerPrototypeNames();Symbol类型,创建要调用函数
  3. 新增了Set和Map两种数据结构,set不可重复,map键值可以是任何类型
  4. Proxy和Reflect
  5. Promise、Generator和Async(Generator的语法糖,自带执行器,返回是promise)
  6. 支持class(实例的原型,static的方法不会被继承,必须new调用)
  7. module(export,import,编译时确定)

闭包及其应用场景

一个函数如果访问了外层作用域的变量,就是闭包

作用:避免命名冲突、解决循环绑定引发的索引问题、使函数内部变量不被销毁

应用场景:

  • 单例模式,变量封装在闭包内部,只向全局暴露一个访问接口
  • 节点循环绑定click事件,比如点击哪个按钮就输出哪个
  • 函数柯里化,避免频繁调用具有相同参数函数
  • 防抖节流

缺点:会出现内存泄漏的问题

防抖节流

对于高频触发的时间,用防抖节流来减少调用频率

  • 防抖:n秒后再执行该事件,如果n秒内重复触发,则重新计时

    搜索框输入、窗口大小调整等

  • 节流:n秒内只运行一次,n秒内重复触发,只有一次生效

    滚动加载、搜索联想

HTTP强缓存和协商缓存

  • 强制缓存

强制缓存在未失效的时候会直接用浏览器的缓存,不会向服务器发送请求

强制缓存生效时状态码为200

相关请求头:cache-control / Expires / Pragma

  • 协商缓存

当第一次请求时服务器返回的响应头没有cache-control / Expires或过期或属性设置为no-cache,浏览器第二次请求时就会与服务器协商,如果没有修改返回304,告诉浏览器可以使用缓存,如果数据有更新则返回200,将更新数据一起返回

相关请求响应头:ETag/If-Not-Match 、Last-Modified/If-Modified-Since

Promise的三种状态

Pending 进行中

Fulfilled 已成功

Rejected 已失败

.then第一个参数是resolve状态的回调函数,第二个是rejected

.catch方法是 .then(null, rejection)的别名,一般用来代替then方法的第二个参数

.finally方法用于不管promise最后状态如何都会执行的操作

all() 多个promise包装成一个新的,都fulfilled才完成,有一个rejected就rejected,但如果promise自己有catch就不会进入all方法的catch

race() 只要有一个promise状态改变就改变

Vue-router的两种模式

Hash和history

  • Hash路由:

工作原理是hashChange事件,url后添加#xxx触发这个事件。#后的hash变化不会导致浏览器向服务器发出请求,即不会刷新页面,触发hashChange事件,通过监听hash值来实现更新页面部分内容

Vue-router默认的是hash模式。

会创建HashHistory对象,访问不同路由时使用HashHistory.push()或HashHistory.replace()

  • History路由:

用H5的pushState()和replaceState()两个api结合window.popstate事件

  • 区别:

pushState设置的url可以试当前url同源的任意url,而hash只能修改#后的部分

pushState设置的url和当前一模一样也会记录到栈中,hash设置的必须不一样才会记录

pushState通过stateObject可以添加任意类型的数据到记录中,hash只可是短字符串

hash兼容IE8以上,history兼容IE10以上

history模式需要后端配合将所有访问都指向index.html,否则会导致404

宏任务和微任务

宏任务 Macrotask是指Event Loop在每个阶段执行的任务

script、setTimeout、setInterval、setImmediate、I/O、UI rendering

微任务 Microtask是指Event Loop在每个阶段间执行的任务

promise.then、process.nextTick、Object.observe、MutationObserve

Js的缺点

  1. 没有命名空间,不好模块化
  2. 全局变量在所有模块中都可见,函数内部也能定义全局变量
  3. 隐式转换:+可以表示相加或者字符连接,==在两个值类型不同的时候会自动转换
  4. NaN表示超出了解释器的极限的数字,有很多奇怪的特性,比如NaN===NaN false
  5. 行尾自动分号插入

数据类型

Number、String、Boolen、Symbol、Null、Undefined、Object

异步、事件循环

Event Loop:主线程会不断从任务队列中按顺序取任务执行,每执行完一个任务都会检查微任务队列是否为空,如果不为空会一次性执行完所有微任务,再进入下一个循环去任务队列中取下一个任务执行。

Async/await:执行到await时若返回的是promise对象会阻塞当前async代码块下面的代码,先执行await中的同步代码,然后执行当前async外的同步代码,等同步代码都执行完后再回到async中,等promise状态达到fulfilled再执行之后的代码。若await返回的不是promise对象,同步代码执行完会回到当前async中执行。

原型

  1. JS的每个对象拥有一个原型,当访问一个对象的属性时,不仅会在对象上搜索还会搜索其原型、原型的原型,层层向上搜索。
  2. 对象的原型有个属性constructor,指向对象本身
  3. 原型分为显式原型和隐式原型,每个对象都有一个隐式原型,指向其构造函数的显式原型,多个_proto_组成的集合称为原型链
  4. 所有的prototype都是对象,所以他们的_proto_指向Object()的prototype
  5. 所有的构造函数的隐式原型都是Funciton的prototype(包括Object._proto_)
  6. Object.prototype的隐式原型是null

继承

子类具有父类的各种属性和方法,不需要再次编写

实现方式:

  • 原型继承:父类实例作为子类的原型,let child = Object.create(father)

不能传参;

Object.create是浅拷贝,多个实例的引用类型指向同一地址,会被篡改

  • 组合继承:子类中用Father.call(this),并且child.prototype = new Father()、child.prototype.constructor = Son,手动挂上构造器,指向自己

可传参,不共享父类引用属;

调用了两次父类构造函数

  • 寄生组合继承:将组合继承的child.prototype = new Father()改成child.prototype = Object.create(Father.prototype)
  • ES6的extend就是寄生组合继承的方式,可以不写constructor,如果写的话第一句要写super,super(200) Father.call(this,200)

xss和csrf是什么,如何防御

  • csrf:跨站请求伪造

    登录了信任网站的情况下,浏览器自动保存了cookie,进入攻击网站,并在攻击网站的诱导下触发对信任网站的请求。由于cookie还在有效期内,请求会被处理

措施:

  1. 使用cookie的sameSite属性的strict,仅允许当前网址与请求的url完全一致时携带cookie(Lax允许部分,get允许,post不允许;None都允许)
  2. 涉及到数据修改的操作严格使用post而非get
  3. HTTP协议中用Refer属性,验证refer是否为自己的域名,来确定请求来源
  4. 请求地址添加token,或自定义属性验证
  5. 显示验证方式,如密码输入,验证码输入等
  • xss:跨站脚本攻击

    通过页面设计时候的缺陷,利用浏览器对某处代码的解析,让浏览器执行恶意代码。如,HTML中内嵌的文本、内联JS、标签的href、src属性、onload/onerror/onclick等事件中注入突破原本限制的代码

    持久型xss:将脚本植入服务器数据库里,导致每个访问的用户都会执行

    非持久型:恶意代码存在url里

措施:

(大部分浏览器都自带xss筛选器,vue等框架也对xss有一些防护)

  1. 对用户输入内容和服务端返回内容进行过滤和转译
  2. 使用cookie的httponly属性,防止用过document.cookie获取cookie
  3. 重要内容加密传输
  4. 对于URL携带的参数谨慎使用
  5. 使用CSP,Content-security-policy请求头,在meta中配置:限制加载其他域的文件、禁止向第三方域提交数据、禁止执行未授权脚本等

讲讲vue框架

Vue是一个用于创建用户界面的js框架,它的核心特性是:

  • MVVM数据驱动

Model模型层:负责处理业务逻辑和服务器进行交互

View视图层:负责将数据模型转化为UI展示出来

ViewModel视图模型层:用来连接M和V,与View之间双向绑定,帮助我们完全避免了对DOM的操作(只操作数据,界面的变动是根据数据双向绑定出来的)

MVC模式:模型 / 视图 / 控制

  • 组件化

Vue允许通过组件来拼装一个页面,每个组件都是一个可复用的Vue实例,组件里可以包含自己的数据,视图和代码逻辑,方便复用

  • 指令系统

带有v-前缀的特殊属性,当表达式的值改变时,响应式地作用于DOM

自定义指令:Vue.directive(),第一个参数是指令名,不带v-;组件options选项中设置directive属性,directive:{ focus:{} }。然后再模板中使用v-focus

讲讲css

  • 盒模型

content、border(粗细,样式,颜色)、padding(受盒子background影响)、margin

标准盒模型:width/height + padding + border + margin

怪异盒模型:width/height + margin,width/height包含了padding和border

  • 选择器

ID(#box)、class(.one)、标签 (p)、通用、属性([attribute] 所有带有attribute属性的元素)、伪类(:hover)、伪元素(::first-line)、子选择器(.one>one_1),相邻选择器(.one+.two 紧接在.one后的所有.two)

!import > 内联 > ID > 类、伪类 > 标签、伪元素 > 子选择器、相邻选择器

数组和字符串有哪些方法

  • 数组

遍历:reduce、map、filter、every、some、forEach

改变:push、pop、shift、unshift、splice、sort、reserve

不变:join、slice、concat

  • 字符串

concat

返回子串:slice、substr、substring

删除空格:trim、trimLeft、trimRight

repeat复制、toLowerCase转小写、toUpperCase转大写

chatAt、indexOf、includes

split转数组

Let和var

  • var

有变量提升,未赋值时是undefined

可重复声明

作用域是方法作用域,在非函数作用域中定义就是全局变量

  • let

声明的变量只在局部起作用

声明前使用会报错

不可重复声明

  • const

有let的所有特性

声明时必须初始化,之后不可更改(实际是地址不可更改)

对http有哪些了解?

  • get、post

get方法请求一个指定资源,应只被用于获取数据;post方法用于将实体提交到指定资源,通常会导致服务器上的状态变化

get回退无害,post会再次提交请求

get请求参数会被完整保留在浏览器历史记录里,post不会

get在url中传送的参数是有长度限制的,post没有

get不安全,因为参数直接暴露在url上,所以不能用来传递敏感信息

get参数通过url传递,post放在request body中

  • 响应码

1消息,2成功,3重定向,4请求错误,5服务器错误

200返回数据;201服务器创建了新资源

301永久移动;302临时移动;

401未授权;403拒绝请求;404找不到请求;405方法错误

502网关错误,上游出问题;503服务不可用;504超时

  • 常见header

Accept 能够接受的回应内容类型

Authorization 认证信息

Cache-control 指定缓存机制

Connection 浏览器想要优先使用的连接类型

Cookie 服务器发送的一个超文本传输协议cookie

Content-Type 请求体的多媒体类型

Content-Type: application/x-www-form-urlencoded

Date 发送该消息的日期

Expect 客户端要求服务器做出的特定行为

Host 服务器的域名和端口号

User-Agent 浏览器的身份标识

Js分片具体怎么做

读取文件的内容,用MD5实现文件的唯一性,然后对文件进行分割(用Blob的slice方法,包含md5值,文件大小,共多少块,第多少块),上传

后端可以根据前端传的md5值,到服务器查找之前文件的合并信息,返回数据告诉前端从第几节上传,实现断点续传

懒加载的原理

访问页面时,先把图片的路径替换成一张占位图的路径,当图片进入可视区域才把图片路径替换成真实路径

监听页面滚动,当元素到浏览器窗口的距离(offsetTop)小于document到浏览器窗口的距离(scrollTop)+可视区域的高度(document.body. clientHeight),img.src改成真实路径

哪些方法能脱离文档流

  1. float 使用时其他盒子会无视该元素,但盒子内的文本依然会为这个元素让出位置,环绕
  2. absolute 绝对定位,相对该元素的父类(不满足就继续向上查询)元素进行定位
  3. fixed 完全脱离文档流,相对于浏览器窗口进行定位

垂直居中有哪些方法

  • position: absolute
  1. top/left/right/bottom都设置为0,margin: auto

  2. top: 50%,margin:负自身的50%,如margin:-50px

  3. top:50%,transform:translate(-50%,-50%)

  • 父类元素display: flex,align-items:center(justify-content:center 水平居中)

Js中堆和栈的储存方式

基本类型存储在栈中,引用类型额对象存储在堆中,引用地址放在栈中

箭头函数和普通函数区别

  1. 箭头函数的this指向它定义时所在对象,而非调用它的对象
  2. 不会进行变量提升
  3. 不可以作为构造函数,不能使用new
  4. 没有arguments对象,如果要用可以用rest
  5. 不可以使用yield命令,所以不能用作Generator函数

v-model原理

实际是v-bind和input事件

:value=”value” @input=”value = $event.target.value”

vue响应式原理

  • vue2是采用发布-订阅者的模式,通过Object.defineProperty()来劫持各个属性的setter、getter。Vue实例创建时,会遍历所有DOM对象,为每个数据属性添加get和set,但添加或删除属性并不会触发;数组是通过重写数组的Array.prototype对应的方法(push/pop/shift/unshift/sort/reverse/splice),触发方法时视图更新
  • Vue3是通过ES6的Proxy,在目标对象外设置一层拦截,外界的操作都会通过这层拦截,可以拦截到对象属性的读取、设置、新增删除等,还可以直接监听数组的变化

vue组件通信

  • props

父传子,子组件设置props属性,接受父组件传来的参数

  • $emit

子传父,通过$emit触发自定义事件,第二个参数为传递的数值,父组件绑定监听器获取组组件传来的参数

  • ref

父组件在使用子组件的时候设置ref属性ref=” xxx”,this.$refs.xxx获取子组件实例

  • EventBus

兄弟组件传值,创建一个中央时间总线EventBus,兄弟组件通过$emit触发自定义事件,另一个兄弟组件通过$on监听自定义事件

  • $parent或$root

兄弟组件传值,通过共同祖辈或root,一个this.$parent.emit(‘add’),另一个this.$parent.on(‘add’, this.add)

  • Attrs和listeners
  • Provide和Inject
  • Vuex

是状态管理工具,集中式存储管理应用的所有组件的状态

State:用来存放共享变量

Getters:相当于计算属性,返回的值会根据它的依赖被缓存起来,只有依赖值发生变化才会被重新计算

Mutations:用来存放修改state中数据的方法,store.commit方法更改数据

Action:通常用来做异步操作,需要在mutation的基础上进行

Module:分割的模块,每个模块拥有自己的state、getters、mutation、actions

diff算法

通过同层的树节点进行比较的算法,只比较同层,循环从两边向中间比较

Vue中用于虚拟DOM渲染成真实DOM的新旧节点比较,

先同级比较,相同则直接复用。

然后比较子节点,如果旧的有子节点,新的没有,会把旧的删除;如果旧的没有新的有,会把新增的子节点插入旧的。

都有子节点时,先比较第一个是否一样,一样的话移动新旧的start指针,不一样则会从最后一个开始比较;如果头尾都不相等则比较新头和旧尾,一样就把旧尾移到前面去,然后end指针往前一位,start指针往后一位。如果存在key则会直接用key去旧的子节点中找,找到就移动到最前面,start往后一位,没有就直接插入。

最后把旧的多余节点删掉。

webpack打包配置

webpack是用于JS应用程序静态模块的打包工具

  • 初始化:从配置文件和shell中读取并合并参数,初始化需要使用的插件和配置插件
  • 编译构建:从Entry出发,对每个Module串行调用对应的Loader进行翻译,再找到该Module依赖的module,递归进行编译
  • 输出:对编译后的Module组合成chunk,转换成文件输出

常用配置:

entry:入口文件,从哪个开始打包

output:输出,打包好的文件输出到哪里

module:配置loader,webpack本身只能打包js/json,打包css、img、html等需要各种loader,通过npm下载即可

plugins:插件

mode:打包模式,development和production

浏览器输入url到网页呈现的过程

  • url解析:协议、域名(确定服务器)、端口(确定服务器中的具体应用)、路径(访问的资源位置)、查询字符串(详细描述)
  • DNS查询:获取到域名对应的服务器的IP地址
  • TCP连接:发送syn,收到发送SYM/ACK的数据包,收到发送标有ACK的数据包
  • 发送http请求:建立tcp连接后发送请求
  • 响应请求:浏览器收到服务器响应的资源,进行解析,开始页面渲染
  • 页面渲染:
  • 解析HTML,构建DOM树
  • 解析CSS,构建CSS规则树
  • 合并DOM树和CSS规则,生成Render树
  • 布局render树,针对浏览器的各种状态,计算各元素的尺寸、位置
  • 绘制render树,绘制页面像素信息
  • 浏览器将各层信息发送给GPU,GPU会将各层合成,显示

前端的优化方法

  • 加载

减少http请求数,合并css和js,使用css精灵图

缓存资源

压缩代码,多余的缩进和换行

样式放在头部使用link引入,脚本放在尾部使用异步加载

懒加载、滚屏加载等按需加载方法

进入页面时先使用loading,加载完成后再显示页面

压缩图像,使用css代替图像

静态资源不适用cookie

  • 执行

避免img、iframe的src为空,空的话会重新加载

避免重置图像大小,会引发重绘

  • 渲染

减少DOM节点

动画尽量使用css3动画,5个元素以上的话使用canvas

使用requestAnimationFrame代替setTimeout

对滚动、鼠标移动这类高频时间使用防抖节流

  • 样式

尽量不在html中写style

避免css表达式

不滥用float,float渲染时计算量比较大

不声明太多的font-size,会影响css树的效率

值为0时不写单位

  • 脚本

尽量改变class而不是style

尽量使用id选择器


本文转载自: https://blog.csdn.net/weixin_44783161/article/details/127452069
版权归原作者 Yquian 所有, 如有侵权,请联系我们删除。

“华为od前端面试题”的评论:

还没有评论