cheny88 / web--issue Goto Github PK
View Code? Open in Web Editor NEW记录重要的面试题呀
记录重要的面试题呀
indexof 方法
语法:stringObject.indexOf(searchvalue, fromindex)
参数:searchvalue 必需。规定需检索的字符串值。 fromindex 可选的整数参数。规定在字符串中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。
说明:该方法将从头到尾地检索字符串 stringObject,看它是否含有子串 searchvalue。开始检索的位置在字符串的 fromindex 处或字符串的开头(没有指定 fromindex 时)。如果找到一个 searchvalue,则返回 searchvalue 的第一次出现的位置。stringObject 中的字符位置是从 0 开始的。如果没有找到,将返回 -1。
/**
使用indexof方法实现模糊查询
@param {Array} list 进行查询的数组
@param {String} keyWord 查询的关键词
@return {Array} 查询的结果
*/
function fuzzyQuery(list, keyWord) {
var arr = [];
for (var i = 0; i < list.length; i++) {
if (list[i].indexOf(keyWord) >= 0) {
arr.push(list[i]);
}
}
return arr;
}
JavaScript中 == 和 === 的详细比较规则
下面分别说明:
先说 ===,这个比较简单。下面的规则用来判断两个值是否===相等:
1、如果类型不同,就[不相等]
2、如果两个都是数值,并且是同一个值,那么[相等];(!例外)的是,如果其中至少一个是NaN,那么[不相等]。(判断一个值是否是NaN,只能用isNaN()来判断)
3、如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等]。
4、如果两个值都是true,或者都是false,那么[相等]。
5、如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。
6、如果两个值都是null,或者都是undefined,那么[相等]。
再说 ==,根据以下规则:
1、如果两个值类型相同,进行 === 比较。
2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较:
a、如果一个是null、一个是undefined,那么[相等]。
b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。
c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。
d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。 js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。
e、任何其他组合,都[不相等]。
————————————————
版权声明:本文为CSDN博主「有范管理美学」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/chenchunlin526/article/details/78850171
看vue源码中判断的顺序:
props => methods => data => computed => watch
父子组件
父组件A通过props向子组件B传递值,子组件B向父组件A传递用:B通过$emit,A通过v-on/@触发
兄弟组件
跨层级组件
生命周期的变化:
beforeCreate、create=>setup
beforeMount=>onBeforeMount
mounted=>onMounted
beforeUpdate=>onBeforeUpdate
updated=>onUpdated
beforeDestroy=>onBeforeUnmount
destroyed=>onUnmounted
errorCaptured=>onErrorCaptured
运行速度:更快
对静态节点进行标记,当进行DOM更新时不再遍历静态节点
object.defineProperty对数组对象的深层监听无法实现,是对对象属性的监听;而Proxy是对整个对象的监听,不存在这个问题。
打包体积:更小
采用webpack中的树plugin删除无用代码
更容易维护、更友好:支持Typescript,代码提示更好,错误提示更强、更容易调试
更容易使用:采用compositions api
长连接:
HTTP 1.0需要使用keep-alive参数来告知服务器端要建立一个长连接,而HTTP1.1默认支持长连接。
HTTP是基于TCP/IP协议的,创建一个TCP连接是需要经过三次握手的,有一定的开销,如果每次通讯都要重新建立连接的话,对性能有影响。因此最好能维持一个长连接,可以用个长连接来发多个请求。
节约带宽
HTTP 1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,才开始把请求body发送到服务器。如果客户端无权限请求服务器,则会返回401状态码(unauthorized未授权),当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。
另外HTTP1.0中,存在一些浪费的现象,例如客户端只是需要某个资源一部分,而服务器却将整个资源送过来了。HTTP1.1在请求头中引入了range头域,允许只请求资源的某一个部分。这样当客户端已经有一部分的资源后,只需要跟服务器请求另外的部分资源即可。这是支持文件断点续传的基础.
HOST头域
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。现在服务器经常设置虚拟站点,多个虚拟站点可以共享同一个ip和端口。HTTP1.0是没有host域的,HTTP1.1才支持这个参数。
多路复用:
HTTP2使用了多路复用的技术,做到同一个连接并发处理多个请求,让所有数据流共用同一个连接,可以更有效地使用 TCP 连接。一个连接上可以有多个request,且可以随机的混在一起,每个不同的request都有对应的id,服务端可以通过request_id来辨别,大大加快了传输速率。
新的二进制格式:
HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2的协议解析决定采用二进制格式,实现方便且健壮。
header压缩
引入头信息压缩机制(header compression),头信息压缩后再发送;客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,不发送同样字段,只发送索引号,提高速度。
服务端推送
HTTP2允许服务器未经请求,主动向客户端发送资源。客户端向服务器请求资源时,服务器可以把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取,避免往返的延迟。
基于UDP,
由于HTTP/2 通过多路复用、二进制流与 Header 压缩等技术,极大地提高了性能,但是还存在问题,比如队头堵塞(HTTP2协议的多路复用机制解决了HTTP层的队头阻塞问题,但是在TCP层仍然存在队头阻塞问题)
TCP协议在收到数据包之后,这部分数据可能是乱序到达的,但是TCP必须将所有数据收集排序整合后给上层使用,如果其中某个包丢失了,就必须等待重传,从而出现某个丢包数据阻塞整个连接的数据使用。
QUIC协议是基于UDP协议实现的,在一条链接上可以有多个流,流与流之间是互不影响的,当一个流出现丢包影响范围非常小,(因为一个流丢包了,只有这个流重传数据包了,别的流不受影响)从而解决队头阻塞问题。
0RTT 建链(RTT:往返时间)
一般来说HTTPS协议要建立完整链接包括:TCP握手和TLS握手,总计需要至少2-3个RTT,普通的HTTP协议也需要至少1个RTT才可以完成握手。
然而,QUIC协议可以实现在第一个包就可以包含有效的应用数据,从而实现0RTT,但这也是有条件的。(对于第一次交互的客户端和服务端0RTT也是做不到的,使用QUIC协议的客户端和服务端要使用1RTT进行密钥交换)
保证了前向安全和前向纠错
前向安全指的是密钥泄漏也不会让之前加密的数据被泄漏,影响的只有当前,对之前的数据无影响。
前面提到QUIC协议首次连接时先后生成了两个加密密钥,由于config被客户端存储了,如果期间服务端私钥泄漏,那么可以根据K = mod p计算出密钥K。
前向纠错利用数据进行传输冗余信息的方法进行数据校验。
QUIC每发送一组数据就对这组数据进行异或运算,并将结果作为一个FEC包发送出去,接收方收到这一组数据后根据数据包和FEC包即可进行校验和纠错。
在移动端的表现比TCP好
QUIC 在移动端的表现也会比 TCP 好。因为 TCP 是基于 IP 和端口去识别连接的,这种方式在多变的移动端网络环境下是很脆弱的,比如,当我们从4G环境切换到wifi环境时,手机的IP地址就会发生变化,这时必须创建新的TCP连接才能继续传输数据。
QUIC协议是通过 ID 的方式去识别一个连接,不管你网络环境如何变化,只要 ID 不变,就能迅速重连上。
总体思路:组件化定义、优点、使用场景和注意事项,vue组件化的特点
结论:
prop:父子之间利用prop传递参数,子父之间利用自定义事件传递参数;
插槽:想扩展一个组件的内容让它变得更通用
并不是vue专用的,其他的框架也在用
必要性:(源码中的mountComponent())vue中一个组件有一个Watcher,一一对应的关系,为了精确的知道在更新的过程中到底谁发生了变化,所以要使用diff。
执行方式:(源码中的patchVnode())patchVnode()是diff发生的地方。整体策略:深度优先,同层比较
高效性:(源码中的updateChildren())
当修改数据触发了setter,setter会触发通知,通知的触发方式是尝试把Watcher添加到异步更新队列,在每一次事件循环结束时要清空队列,清空队列的过程中,所有的Watcher尝试它们的更新函数,更新函数在执行时调用了组件的渲染函数以及组件的更新函数,这时候会重新渲染最新的虚拟DOM,然后执行更新函数比较新旧虚拟DOM,此时diff真正的触发了。
结论:
使用Vue.mixin全局混入
很多地方会用到公共的代码=>实现代码复用
mixin中放钩子函数的执行顺序:全局的mixin=>组件的mixin=>组件自身的钩子
加slot扩展
slot用来获取组件中的原内容
默认插槽(如果有个组件希望这个按钮有默认内容,但是又同时允许用户复写为别的内容)
具名插槽(组件中有多个插槽,用名字区分)
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script type="text/javascript">
window.onload = function () {
let oBtn1 = document.getElementById("btn1");
let oBox = document.getElementById("box");
let oInputs = oBox.getElementsByTagName("input");
oBtn1.onclick = function () {
if (oBtn1.checked == true) {
for (let i = 0; i < oInputs.length; i++) {
oInputs[i].checked = true;
}
} else {
for (let i = 0; i < oInputs.length; i++) {
oInputs[i].checked = false;
}
}
};
//点击每一个input框
for (let i = 0; i < oInputs.length; i++) {
oInputs[i].onclick = function () {
let n = 0;
for (let i = 0; i < oInputs.length; i++) {
if (oInputs[i].checked == true) {
n++;
}
}
if (n == oInputs.length) {
oBtn1.checked = true;
} else {
oBtn1.checked = false;
}
};
}
};
</script>
</head>
<body>
<h1>全选/全不选</h1>
<input type="checkbox" id="btn1"/>
<div id="box">
<input type="checkbox" name="" />
<input type="checkbox" name="" />
<input type="checkbox" name="" />
<input type="checkbox" name="" />
</div>
</body>
</html>
源码中组件 初始化data时的initData,会判断传进来的data是不是函数,如果是函数,就执行,如果不是函数就用之前统一定义的data
而根实例不走这个判断,走的是,拿到实例进行操作,普通组件因为当时还没有实例,所以没有这步。
在组件中如果data是对象,会报错,无法通过vue检测
结论:
vue组件可能存在多个实例,如果使用对象形式定义data,则会导致它们共用一个data对象,那么状态变更将会影响所有组件实例,这是不合理的;采用函数形式定义(函数每次执行都会返回全新data对象实例),在initData时会将其作为工厂函数返回一个全新data对象,有效规避多实例之间状态的污染问题。
而在根实例创建过程中则不存在该限制,也是因为根实例只能有一个,不需要担心这种情况。
<p v-for="child in children" v-if="isFolder">{{child.title}}</p>
//<script>中的代码如下:
const app=new Vue({
el:"#app",
data(){
return {
children:[
{tiltle:"foo"}
{tiltle:"bar"}
]
}
}
})
原因:源码generation element中在处理AST时,先if看 静态节点,再else if看once,再else if 看for,然后再else if 看if
改成 :
<template v-if="isFolder">
<p v-for="child in children">{{child.title}}</p>
</template>
注意:此时判断的是children显不显示
如果是children选项内部的child有条件判断,例如:
const app=new Vue({
el:"#app",
data(){
return {
children:[
{tiltle:"foo",isShow:true}
{tiltle:"bar",isShow:false}
]
}
}
})
这样不得不在循环的内部做判断,如何优化?
用一个计算属性去做过滤,把需要渲染的才留下,不需要渲染的就不放到循环中,所以,模板中提供的数组应该是由计算属性处理过的需要渲染的项,不在循环内部判断。
此处说的是vue性能优化,不提web优化的方法
const router=new Vuerouter({
router:[
{ path:'/foo', component:()=>import('./Foo.vue') }
]
})
事件的销毁:在beforeDestroy中销毁定时器(clearInterval)
图片懒加载(vue-lazylaod库)
第三方插件按需引入(例如element-ui按需引入)
import Vue from 'vue';
import { Button, Select } from 'element-ui';
Vue.use(Button)
Vue.use(Select)
简单请求vs非简单请求
揭秘简单请求与复杂请求
options请求(跨域预检)
除简单请求以外的都是非简单请求,又叫复杂请求和预检请求。比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求中,浏览器需要最先发送的是一种"预请求",此时作为服务端,也需要返回"预回应"作为响应。预请求实际上是对服务端的一种权限请求,只有当预请求成功返回,实际请求才开始执行。
预请求以OPTIONS形式发送,当中同样包含Origin,并且还包含了两项CORS特有的内容
Access-Control-Request-Method – 该项内容是实际请求的种类,可以是GET、POST之类的简单请求,也可以是PUT、DELETE等等。
Access-Control-Request-Headers – 该项是一个以逗号分隔的列表,当中是复杂请求所使用的头部。
复杂请求的后续数据发送:一旦服务器通过了"预检"请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。
(CORS-preflight 预检请求 就是这样一种机制,浏览器先单独请求一次,询问服务器某个资源是否可以跨源,如果不允许的话就不发实际的请求。注意先许可再请求等于默认禁止了跨源请求。如果允许的话,浏览器会记住,然后发实际请求,且之后每次就都直接请求而不用再询问服务器否可以跨源了。)
webpack是一个模块化打包JS的工具,在webpack中一切文件都是模块,通过定义entry.js对所有依赖的文件进行跟踪,将各个模块通过loader(转换文件)和plugin(注入钩子)处理,然后打包成bundle.js文件,通过代码分割成单元片段并按需加载。
打包过程中webpack根据code splitting功能将文件分为多个chunks,还可以将重复的部分单独提取出来作为commonChunk,从而实现按需加载。
bundle:是由webpack打包出来的文件
chunk:是一个代码块,一个chunk由多个模块组合而成
module:是开发中的单个模块。
在wenpack中一切都是模块,一个模块对应一个文件,webpack会从配置的entry(入口)中递归开始查找所有模块
loader: 因为webpack本身只理解JavaScript,所以loader用来解析js以外的东西,用于告诉 Webpack 在遇到哪些文件时使用哪些Loader 去加载和转换打包成js。
常用loader:
css-loader——读取合并CSS 文件、
style-loader——把CSS代码注入到JavaScript中,通过DOM操作去加载CSS、
url-loader——将文件转换为base64的方式、
vue-loader——处理vue文件、
babel-loader——把ES6转换成ES5、
eslint-loader——通过ESLint检查JavaScript代码
plugin: 插件,用来扩展webpack功能,针对的是在loader结束之后,webpack打包的整个过程,他并不直接操作文件,而是基于事件机制工作,监听webpack打包过程中的某些节点,在合适的机会通过webpackt提供的API改变输出结果。
常用Plugin:
define-plugin——定义环境变量
commons-chunk-plugin——提取公共代码
uglifyjs-webpack-plugin——通过UglifyES压缩ES6代码
Webpack的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:
源码的patch过程中,会执行patchVnode,patchVnode过程中会执行updateChildren()方法更新新旧子元素,在这过程中通过key可以精准的判断当前两个元素节点是不是同一个节点。
结论:
key的作用主要是为了高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
另外,若不设置key还可能在列表更新时引发一些隐蔽的bug
vue中在使用相同标签名元素的过渡transition切换时,也会用到key属性,其目的也是为了让vue可以区分他们,否则vue只会替换其内部属性而不会触发动画的过渡效果
CDN是一种公共服务,他本身有很多台位于不同地域、接入不同运营商的边缘服务器。
使用CDN实质上就是让CDN作为网站的门面,用户访问到的是就近的CDN服务器,就近的而不是直接访问到网站。使用户就近获取所需数据。
由于CDN内部对TCP的优化、对静态资源的缓存、预取,加上用户访问CDN时,会被智能的分配到最近的节点,降低网络大量延迟,让访问速度可以得到很大提升。
可以将一些大的库放上去,首先打开package.json看看有哪些可以进行CDN优化,例如可以将vue、vue-router、element-ui、echarts都放在CDN上。
三种形式:
全局导航钩子
路由配置中的导航钩子
组件内部导航钩子
全局导航钩子
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.