华为前端笔试(华为od前端面试题)
目录
es6新特性
闭包及其应用场景
防抖节流
HTTP强缓存和协商缓存
Promise的三种状态
Vue-router的两种模式
宏任务和微任务
Js的缺点
数据类型
异步 、事件循环
原型
继承
xss和csrf是什么 ,如何防御
讲讲vue框架
讲讲css
数组和字符串有哪些方法
Let和var
对http有哪些了解?
Js分片具体怎么做
懒加载的原理
哪些方法能脱离文档流
垂直居中有哪些方法
Js中堆和栈的储存方式
箭头函数和普通函数区别
v-model原理
vue响应式原理
vue组件通信
diff算法
webpack打包配置
浏览器输入url到网页呈现的过程
前端的优化方法
es6新特性
let 、const、块级作用域;解构赋值 一些原生对象新增了方法 ,比如string的模板字符串;函数的默认值 、箭头函数;数组的扩展运算符;对象名可以简写(key,value相同时可以只写一个) 、Object.is() 、Object.assign() 、遍历对象:for-in 、Object.keys() 、Object.getOwnerPrototypeNames();Symbol类型 ,创建要调用函数 新增了Set和Map两种数据结构 ,set不可重复 ,map键值可以是任何类型 Proxy和Reflect Promise 、Generator和Async(Generator的语法糖 ,自带执行器 ,返回是promise) 支持class(实例的原型 ,static的方法不会被继承 ,必须new调用) 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的缺点
没有命名空间 ,不好模块化 全局变量在所有模块中都可见,函数内部也能定义全局变量 隐式转换:+可以表示相加或者字符连接 ,==在两个值类型不同的时候会自动转换 NaN表示超出了解释器的极限的数字 ,有很多奇怪的特性,比如NaN===NaN false 行尾自动分号插入数据类型
Number 、String 、Boolen 、Symbol 、Null 、Undefined、Object
异步 、事件循环
Event Loop:主线程会不断从任务队列中按顺序取任务执行 ,每执行完一个任务都会检查微任务队列是否为空 ,如果不为空会一次性执行完所有微任务,再进入下一个循环去任务队列中取下一个任务执行 。
Async/await:执行到await时若返回的是promise对象会阻塞当前async代码块下面的代码 ,先执行await中的同步代码 ,然后执行当前async外的同步代码 ,等同步代码都执行完后再回到async中 ,等promise状态达到fulfilled再执行之后的代码 。若await返回的不是promise对象 ,同步代码执行完会回到当前async中执行 。
原型
JS的每个对象拥有一个原型 ,当访问一个对象的属性时 ,不仅会在对象上搜索还会搜索其原型 、原型的原型 ,层层向上搜索 。 对象的原型有个属性constructor ,指向对象本身 原型分为显式原型和隐式原型,每个对象都有一个隐式原型 ,指向其构造函数的显式原型 ,多个_proto_组成的集合称为原型链 所有的prototype都是对象,所以他们的_proto_指向Object()的prototype 所有的构造函数的隐式原型都是Funciton的prototype(包括Object._proto_) 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还在有效期内,请求会被处理
措施:
使用cookie的sameSite属性的strict ,仅允许当前网址与请求的url完全一致时携带cookie(Lax允许部分 ,get允许,post不允许;None都允许) 涉及到数据修改的操作严格使用post而非get HTTP协议中用Refer属性 ,验证refer是否为自己的域名 ,来确定请求来源 请求地址添加token ,或自定义属性验证 显示验证方式 ,如密码输入 ,验证码输入等 xss:跨站脚本攻击通过页面设计时候的缺陷 ,利用浏览器对某处代码的解析 ,让浏览器执行恶意代码 。如 ,HTML中内嵌的文本 、内联JS 、标签的href、src属性 、onload/onerror/onclick等事件中注入突破原本限制的代码
持久型xss:将脚本植入服务器数据库里 ,导致每个访问的用户都会执行
非持久型:恶意代码存在url里
措施:
(大部分浏览器都自带xss筛选器,vue等框架也对xss有一些防护)
对用户输入内容和服务端返回内容进行过滤和转译 使用cookie的httponly属性 ,防止用过document.cookie获取cookie 重要内容加密传输 对于URL携带的参数谨慎使用 使用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 、postget方法请求一个指定资源 ,应只被用于获取数据;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超时
常见headerAccept 能够接受的回应内容类型
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改成真实路径
哪些方法能脱离文档流
float 使用时其他盒子会无视该元素,但盒子内的文本依然会为这个元素让出位置 ,环绕 absolute 绝对定位 ,相对该元素的父类(不满足就继续向上查询)元素进行定位 fixed 完全脱离文档流,相对于浏览器窗口进行定位垂直居中有哪些方法
position: absolute1) 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中堆和栈的储存方式
基本类型存储在栈中 ,引用类型额对象存储在堆中 ,引用地址放在栈中
箭头函数和普通函数区别
箭头函数的this指向它定义时所在对象 ,而非调用它的对象 不会进行变量提升 不可以作为构造函数 ,不能使用new 没有arguments对象,如果要用可以用rest 不可以使用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选择器
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!