let url = 'http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,'
function geturl(url) {
//在外面定义一个空变量用来输出最后的对象
var obj = {
}
//判断这个url里面存不存在参数
// console.log(url.match(/\?/g));
if (/\?/g.test(url)) {
//取出?号后面的字符串 这个用的是substring方法 找到?后面的哪一位的索引
var urlstring = url.substring(url.indexOf('?') + 1)
console.log(urlstring)
//之后按 &符号拆分成数组
var urlarry = urlstring.split('&')
console.log(urlarry)
//遍历拆分的数组 之后再把数组按 “=”号拆分
urlarry.forEach(function (v, i) {
console.log(v, i)
let z = v.split('=')
console.log(z)
//之后拼接起来 把obj返回出去
obj[z[0]] = z[1]
})
// console.log(obj);
return obj
}
}
console.log(geturl(url))
for (vari = 1; i <= 3; i++) {
setTimeout(function () {
console.log(i)
}, 0)
}
// 输出 4 4 4 因为settiomeout是异步的所以是for循环先执行。
// 如何让上述代码输出 1 2 3呢?
for (var i = 1; i <= 3; i++) {
setTimeout(
((function (a) {
console.log(a)
})(i),
0)
)
}
// 只需要让setTimeout里面的函数变成 自执行,或者立即执行函数,然后就可以输出结果 1 2 3 了。 或者改成let 。
// 只有一个作用:创建一个独立的作用域。
//立即执行函数的作用:这个作用域里面的变量,外面访问不到(即避免「变量污染」)
在实例完全被创建出来之前,当前只有 watch 对象,el 跟 data 都没有挂载完毕的时候,触发的钩子。
这个时候,实例已经被创建了出来,这时候如果想要触发 method 的函数以及获取到请求数据进行修改数据的时候可以在这个钩子里面进行,这个时候 data 数据已经更新$el 属性目前还没有被挂载。
在这个阶段 el 以及 data 元素都已经完全准备完毕,虚拟 dom 也准备完毕,但是还没有渲染到页面之中,所以页面中的元素还没有进行更改此时。此时可以拿到 vm.$el,但是是没有更新的旧模板。
这个阶段是实例以及虚拟 dom 都被挂载完毕的阶段,data 以及 el 中的东西都已经被更新渲染到页面上了,也就是用户看到的页面,在这个函数执行完毕之后就代表整个初始渲染都加载完毕了,在这个函数是实例创建期间最后一个生命周期函数。如果想要在这个期间获取到 dom 元素的话,在上面的钩子函数中可以加 vm.$nextTick()函数表示 dom 渲染完毕之后的回调 ,这个回调函数也是发生在 mounted 挂载后前所调用的回调函数。
msp; 这个期间的钩子表示,数据发生改变的但是 dom 元素还没有改变的期间,这个期间 data 已经被改变了,但是 dom 元素还没有被更新。
这个顾名思义就是发生在虚拟 dom 已经替换掉页面中元素后执行的钩子,表明虚拟 dom 以及数据都已经更新完毕。
这个表明在实例销毁前仍然可以使用整个 vue 实例对象,在这个阶段可以销毁定时器等一些操作在销毁后前想要做的最终操作。
组件以及整个实例被销毁后触发,这时整个 vue 生命周期结束,vue 实例解除对 dom 的观察以及对数据的绑定,这时候改变数据跟 dom 都没有效果,但是被最终操作后的 dom 结构树依旧存在在页面中。
首先:如果是存在上个 url 跳转到另一个 url 的情况,前面会先触发 beforeRouteLeave 守卫。
自底向上有:
物理层······· 二进制在物理媒体上传输数据 (ISO2110、IEEE802、IEEE802.2)
数据链路层······· 传输有地址的帧跟错误检测(SLIP、CSLP、PPP、ARP、RARP、MTU)
网络层······· 为数据包选择路由(IP、ICMP、RIP、OSPF、BGP、IGMP)
传输层······· 提供端对端的接口(TCP、UDP)
会话层······· 解除或建立与别的节点的联系(没有协议)
表示层······· 数据格式化,代码转换,数据加密(没有协议)
应用层·······文件传输、电子邮件、文件服务、虚拟终端(TFTP、HTTP、SNMP、FTP、SMTP、DNS、Telhet)
浅拷贝与深拷贝都是对于引用类型来说的,浅拷贝就是复制对象的引用,浅拷贝如果改变了复制对象的值,那么其源对象的值也会发生改变。,深拷贝就是对象的彻底拷贝,不值拷贝你用类型,也复制了值。只要进行深拷贝就是代表两个对象之间没有了联系。
function deepClone(source) {
const targetObj = source.constructor === Array ? [] : {
} // 判断复制的目标是数组还是对象
for (let keys in source) {
// 遍历目标
if (source.hasOwnProperty(keys)) {
//如果是继承的属性 就返回false 就相当于判断这个属性keys属不属于自身
if (source[keys] && typeof source[keys] === 'object') {
// 如果值是对象,就递归一下
targetObj[keys] = source[keys].constructor === Array ? [] : {
}
targetObj[keys] = deepClone(source[keys])
} else {
// 如果不是,就直接赋值
targetObj[keys] = source[keys]
}
}
}
return targetObj
}
let Newtarget = JSON.parser(JSON.stringify(target))
// 这种是简单的深拷贝 但是不能拷贝,function 跟 undefined 类型的值。
json 进行深拷贝,不能拷贝 function,跟 undefined。
1. 什么是内存泄漏?
2. 内存泄漏的原因
1、使用工具 Heap Profiling
①、Heap Profiling 可以记录当前的堆内存(heap)的快照,并生成对象的描述文件,该描述文件给出了当时 JS 运行所用的所有对象,以及这些对象所占用的内存大小、引用的层级关系等等。
②、JS 运行的时候,会有栈内存(stack)和堆内存(heap),当我们 new 一个类的时候,这个 new 出来的对象就保存在 heap 里,而这个对象的引用则存储在 stack 里。程序通过 stack 的引用找到这个对象。例如:var a = [1,2,3],a 是存储在 stack 中的引用,heap 里存储着内容为[1,2,3]的 Array 对象。
③、打开调试工具,点击 Memory 中的 Profiles 标签,选中“Take Heap Snapshot”,点击“start”按钮,就可以拍在当前 JS 的 heap 快照了。
将上图框框切换到 comparison(对照)选项,该视图列出了当前视图与上一个视图的对象差异
New:新建了多少对象
Deleted:回收了多少对象
Delta:新建的对象个数减去回收的对象个数
重点看 closure(闭包),如果#Delta 为正数,则表示创建了闭包函数,如果多个快照中都没有变负数,则表示没有销毁闭包
因为浏览器存在缓存机制,而且浏览器的缓存机制是为了防止用户想服务器多次发送相同的请求,机制原理是,当浏览器在第一次访问网站之后会生成一份缓存文件,如果下次访问的时候,文件的路径跟缓存中路径存在重复的情况他就不会重复想服务器发送请求,会从缓存中读取请求。这种机制有优缺点,优点:可以减轻服务器压力 ,提升下次打开网站的时候用户体验。缺点:比如在做验证码功能的时候你需要穿一个参数不停的去改变路径才可以使验证码每次点击都会被刷新。或者在引用 js
等 css 脚本的时候。添加一个版本号。
1. Array.from //把伪数组变成真数组
2. Set() //去除重复数组
3. forEach //数组循环
4. map // 也是遍历,只不过是有返回值
5. filter //数组过滤 return 过滤条件 返回值也是一个数组
6. every // 当所有的元素都满足条件的时候返回一个true 在每次判断的时候都是返回一个布尔值,也是也是一个判断性数组
7. some // 当循环遍历的时候 有一个 为true 直接返回数组
8. indexof //寻找 数组中存在的元素的下标 如果存在返回一 否则返回 -1
9. sort //数组的排序方法 a-b是升序 b-a 是降序 返回值为负数放在前面 正数放在后面 引出冒泡排序的原理
10.
// 定义一个 promise函数
function promiseAll(promises) {
// 在这里直接return 一个promise对象 是为了执行 里面promise函数的
return new Promise((resolve, reject) => {
// 把两个promise数组对象扔进去 在这里设定一个计时器 来计算promise函数 执行了几个了
let resultCount = 0
//这里严格意义要用new array来创建一个 有多少个参数长度的空数组 在后面放值的时候要使用
let result = new Array(promises.length)
// new一个空数组是为了 把传进来的promise函数的结果 放在数组中 最后用promise函数 resolve参数接受到 并在最后then出去
// let result = [];
for (let i = 0; i < promises.length; i++) {
//循环所有的promise 如果.then执行了 就代表 这个promise对象执行了 用计数器进行计数 并把结果返回到一个新的数组中
//这里用 对应执行的 promise函数都有着对应的返回值 把他存到数组中
promises[i].then((res) => {
resultCount++
// result.push(res);
// 这里用result[i]来接受 返回值是为了
result[i] = res
//这里判断 计数器执行的次数是否跟传进的参数相等,如果相等 就表示 所有的promise执行完毕了 就可以吧结果反悔了
if (resultCount === promises.length) {
return resolve(result)
}
//这里是错误的捕捉 如果发生错误 就返回错误信息
}),
(error) => {
reject(error)
}
}
})
}
//测试 测试 测试
let p2 = new Promise((resolve) => resolve('p2'))
let p1 = new Promise((resolve) => resolve('p1'))
// let p3 = Promise.reject('p3 error')
promiseAll([p2, p1])
.then((results) => {
console.log(results) // ['p1', 'p2']
})
.catch((error) => {
console.log(error)
})
/* promiseAll([p1, p2, p3]).then(results => {
console.log(results)
}).catch(error => {
console.log(error) // 'p3 error'
}) */
arr.form() 把伪数组变成真数组。
sort 排序 a-b 取第一位 。升序是 b-a 取最后一位
优点:弱类型使用简单,更灵活多变。
缺点:在代码的上线稳重,可能会进行隐式类型转换,会稍微损耗性能,可能不符合程序的本意。
arr.from() 把伪数组变成真数组并进行浅拷贝类的实例。
• 捕获阶段:事件对象从目标的祖先节点 Window 开始传播直至目标。
• 目标阶段:事件对象传递到事件目标。如果事件的 type 属性表明后面不会进行冒泡操作,那么事件到此就结束了。
• 冒泡阶段:事件对象以一个相反的方向进行传递,从目标开始,到 Window 对象结束。
使用 delete 删除对象属性。
全称:Search English Optimization,搜索引擎优化。自从有了搜索引擎,SEO 便诞生了。
存在的意义:为了提升网页在搜索引擎自然搜索结果中的收录数量以及排序位置而做的优化行为。简言之,就是希望百度等搜索引擎能多多我们收录精心制作后的网站,并且在别人访问时网站能排在前面。
分类:白帽 SEO 和黑帽 SEO。白帽 SEO,起到了改良和规范网站设计的作用,使网站对搜索引擎和用户更加友好,并且网站也能从搜索引擎中获取合理的流量,这是搜索引擎鼓励和支持的。黑帽 SEO,利用和放大搜索引擎政策缺陷来获取更多用户的访问量,这类行为大多是欺骗搜索引擎,一般搜索引擎公司是不支持与鼓励的。本文针对白帽 SEO,那么白帽 SEO 能做什么呢?
对网站的标题、关键字、描述精心设置,反映网站的定位,让搜索引擎明白网站是做什么的;
网站内容优化:内容与关键字的对应,增加关键字的密度;
在网站上合理设置 Robot.txt 文件;
生成针对搜索引擎友好的网站地图;
增加外部链接,到各个网站上宣传;
通过网站的结构布局设计和网页代码优化,使前端页面既能让浏览器用户能够看懂,也能让“蜘蛛”看懂。
(1) 网站结构布局优化:尽量简单、开门见山,提倡扁平化结构。
一般而言,建立的网站结构层次越少,越容易被“蜘蛛”抓取,也就容易被收录。一般中小型网站目录结构超过三级,“蜘蛛”便不愿意往下爬,“万一天黑迷路了怎么办”。并且根据相关调查:访客如果经过跳转 3 次还没找到需要的信息,很可能离开。因此,三层目录结构也是体验的需要。为此我们需要做到:
网站首页是权重最高的地方,如果首页链接太少,没有“桥”,“蜘蛛”不能继续往下爬到内页,直接影响网站收录数量。但是首页链接也不能太多,一旦太多,没有实质性的链接,很容易影响用户体验,也会降低网站首页的权重,收录效果也不好。
因此对于中小型企业网站,建议首页链接在 100 个以内,链接的性质可以包含页面导航、底部导航、锚文字链接等等,注意链接要建立在用户的良好体验和引导用户获取信息的基础之上。
2.扁平化的目录层次,尽量让“蜘蛛”只要跳转 3 次,就能到达网站内的任何一个内页。扁平化的目录结构,比如:“植物”–> “水果” –> “苹果”、“桔子”、“香蕉”,通过 3 级就能找到香蕉了。
3.导航优化
导航应该尽量采用文字方式,也可以搭配图片导航,但是图片代码一定要进行优化,
其次,在每一个网页上应该加上面包屑导航,好处:从用户体验方面来说,可以让用户了解当前所处的位置以及当前页面在整个网站中的位置,帮助用户很快了解网站组织形式,从而形成更好的位置感,同时提供了返回各个页面的接口,方便用户操作;对“蜘蛛”而言,能够清楚的了解网站结构,同时还增加了大量的内部链接,方便抓取,降低跳出率。
1)页面头部:logo 及主导航,以及用户的信息。
2)页面主体:左边正文,包括面包屑导航及正文;右边放热门文章及相关文章,好处:留住访客,让访客多停留,对“蜘蛛”而言,这些文章属于相关链接,增强了页面相关性,也能增强页面的权重。
3)页面底部:版权信息和友情链接。
特别注意:分页导航写法,推荐写法:“首页 1 2 3 4 5 6 7 8 9 下拉框”,这样“蜘蛛”能够根据相应页码直接跳转,下拉框直接选择页面跳转。而下面的写法是不推荐的,“首页 下一页 尾页”,特别是当分页数量特别多时,“蜘蛛”需要经过很多次往下爬,才能抓取,会很累、会容易放弃。
5.控制页面的大小,减少 http 请求,提高网站的加载速度。
一个页面最好不要超过 100k,太大,页面加载速度慢。当速度很慢时,用户体验不好,留不住访客,并且一旦超时,“蜘蛛”也会离开。
(2) 网页代码优化
1.标题:只强调重点即可,尽量把重要的关键词放在前面,关键词不要重复出现,尽量做到每个页面的
2.标签:关键词,列举出几个页面的重要关键字即可,切记过分堆砌。
3.标签:网页描述,需要高度概括网页内容,切记不能太长,过分堆砌关键词,每个页面也要有所不同。
4.中的标签:尽量让代码语义化,在适当的位置使用适当的标签,用正确的标签做正确的事。让阅读源码者和“蜘蛛”都一目了然。比如:h1-h6 是用于标题类的,
5.标签:页内链接,要加“title” 属性加以说明,让访客和 “蜘蛛” 知道。而外部链接,链接到其他网站的,则需要加上 el="nofollow"属性, 告诉 “蜘蛛” 不要爬,因为一旦“蜘蛛”爬了外部链接之后,就不会再回来了。
6.正文标题要用
7.
标签:只用于文本内容的换行,比如:
第一行文字内容
第二行文字内容
第三行文字内容
9.应使用 “alt” 属性加以说明
10.、标签 : 需要强调时使用。标签在搜索引擎中能够得到高度的重视,它能突出关键词,表现重要的内容,标签强调效果仅次于标签。
、标签: 只是用于显示效果时使用,在 SEO 中不会起任何效果。
11、文本缩进不要使用特殊符号 应当使用 CSS 进行设置。版权符号不要使用特殊符号 © 可以直接使用输入法,拼“banquan”,选择序号 5 就能打出版权符号 ©。
12、巧妙利用 CSS 布局,将重要内容的 HTML 代码放在最前面,最前面的内容被认为是最重要的,优先让“蜘蛛”读取,进行内容关键词抓取。
13.重要内容不要用 JS 输出,因为“蜘蛛”不认识
14.尽量少使用 iframe 框架,因为“蜘蛛”一般不会读取其中的内容
15.谨慎使用 display:none :对于不想显示的文字内容,应当设置 z-index 或设置到浏览器显示器之外。因为搜索引擎会过滤掉 display:none 其中的内容。
17.js 代码如果是操作 DOM 操作,应尽量放在 body 结束标签之前,html 代码之后。
先执行父组件 beforecreate 在执行 created 之后执行 子组件的 beforecreate 一直到 mounted 之后再执行父组件的 beforemount 跟 mounted。