重点面试题目
1.BFC 的形成条件
- 简称块级格式化上下文。
- 如何形成的 bfc?当元素是浮动元素、绝对定位的元素,以及是非块级盒子的块级元素如*(inline-block、table-cells、table-captions)*最后还有 overflow 的属性不是 visible(他是 overfllow 的默认属性)的块级盒子 ,在这些元素的内部都会创建出一个 BFC。
2. 有这样一个 URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段 JS 程序提取 URL 中的各个 GET 参数(参数名和参数个数不确定),将其按 key-value 形式返回到一个 json 结构中,如{a:’1′,b:’2′,c:”,d:’xxx’,e:undefined}。
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))
3.以下内容输出的结果是什么?
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 。
// 只有一个作用:创建一个独立的作用域。
//立即执行函数的作用:这个作用域里面的变量,外面访问不到(即避免「变量污染」)
4. 前端查询 UA 信息的方式
- navigator.userAgent 可以查询 UA 信息
5. 什么是闭包?闭包的优缺点?
- 闭包是一种现象,现象的表现是,当一个存在于另一个函数内部的函数可以访问其外部函数的变量的这种现象被称为闭包。在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
- 闭包的优点是,局部变量不会污染全局变量,在全局情况下可以访问其函数内部的变量。可以让变量私有化。
- 缺点是,因为形成闭包之后,外部函数中的变量会被内部函数所绑定,所以在函数执行完毕之后,其外部函数内部的作用域不会被销毁,所以变量会一直存在会造成内存泄露的问题。还有影响其系统性能的问题。
6. 什么是原型,原型链?
- 每个函数中都存在一个 prototype(原型)这个属性,这个属性是一个指针,指向了一个对象,这个对象拥有所有的原型对象的方法,这个原型对象就是用来给所有的实例共享属性跟方法的。每个实例内部都又存在着一个指向该原型对象的指针(proto),我们可以在实例上调用这个指针来查找到与之对应的原型对象。在其每一个原型对象上又拥有一个 constructor 属性,这个属性值指向这个原型对象的所与之关联的构造函数。每个实例中的 prototype 都指向这个构造函数的原型对象。
- proto 与 prototype 的区别?在每一个函数对象里面都拥有着一个函数指针,在实例上找不到 prototype 这个函数指针在标准浏览器之中有着proto指针,这个指针也是指向这个实例的与之相关构造函数的原型对象。也能够找到与之对象的该函数的原型。
- 什么是原型链?? 原型链顾名思义是一个链条,因为刚才说过每一个函数中都存在有一个 prototype 属性,这个属性指向与之对应的原型对象,当然原型对象上他也有这个 prototype 属性,他会指向他原型对象的原型对象,当自身实例在自己身上找不到属性的时候,他就会一级一级向自身的原型上去寻找直到找到 object 这个原型对象为止,如果找不到才会停止寻找,这个 object 对象是所有的函数的根原型,一般系统内置的函数中的方法都存在于改对象之中。
- 原型、构造函数、于实例的关系?
他们三者的关系可以这样理解,原型中存在一个 constructor 这个属性指向与他相关的构造函数,构造函数中又存在一个 prototype 属性指向该原型的原型对象,在实例中并不存在 prototype 这个属性只有 proto 这个指针,他跟 prototype 同理,也指向改实例的原型对象。所以三者的关系是实例跟构造函数的指向原型对象。
7. 什么是作用域,作用域链?
- 作用域就是指代码执行的时候所处在的环境,而全局执行环境就是指全局作用域,函数执行的环境就被成为局部作用域,他们都在栈内存中开辟新的空间。
- 执行环境决定了处在环境中的函数变量是否有权限访问其他的数据,每一个环境都有一个与之相关的变量对象,环境中的定义的变量跟函数都保存在这个对象中。
- 全局执行的环境是处在最外部的一个执行环境,根据 ES 实现所处的环境不同,表示执行环境的对象不同:可以有两个对象,在 web 浏览器中,全局环境是指 window 对象,因为所有的全局变量跟函数都是为了 window 所准备的。在 node 环境中,全局环境是指 global 对象。
- 在某个环境中,函数执行完毕之后,他所在的环境跟变量会被销毁,但是全局环境的作用域跟变量只会在你关闭页面或者浏览器的时候才会被销毁。所以在 js 中有四个概念:
私有作用域–>在函数执行的时候形成的一个私有环境,就叫私有作用域。
全局作用域–>在一个浏览器或者页面一打开的时候就形成的环境,就被成为全局作用域。
私有变量–>在函数中形成或者定义的变量就是私有变量。
全局变量–>处在全局作用域或者环境中的变量被成为全局变量。 - 什么是作用域链?
在代码所执行的环境中会给创建变量的对象创造一个作用域链。
作用域链的前端就是指当前执行代码所处的环境对象。
作用域的下一级就是来自于改作用域对象的外部环境的下一个对象。一只到最终全局的环境对象。
作用域链的顶端就是全局作用域环境对象。
内部环境的变量可以访问其外部环境的变量,反之则不可以。在一个函数访问变量的过程中,首先会在自身查找这个变量,如果自身差找不到则会按照作用域链查找上一级的环境对象。一层层向上寻找直到找到作用域的顶端,全局作用域对象,这种变量寻找机制也就被称为作用域链。
这样也就说明了为什么在访问变量的时候局部变量的执行速度会被全局变量的执行速度要快的原因。
8. vue 的生命周期?
vue 的生命周期一共有八种状态,创建前/后、载入前/后、更新前/后、销毁前/后。
- beforeCreate(创建前)
在实例完全被创建出来之前,当前只有 watch 对象,el 跟 data 都没有挂载完毕的时候,触发的钩子。
- Created(创建后)
这个时候,实例已经被创建了出来,这时候如果想要触发 method 的函数以及获取到请求数据进行修改数据的时候可以在这个钩子里面进行,这个时候 data 数据已经更新$el 属性目前还没有被挂载。
- beforeMount(挂载前)
在这个阶段 el 以及 data 元素都已经完全准备完毕,虚拟 dom 也准备完毕,但是还没有渲染到页面之中,所以页面中的元素还没有进行更改此时。此时可以拿到 vm.$el,但是是没有更新的旧模板。
- Mounted(挂载后)
这个阶段是实例以及虚拟 dom 都被挂载完毕的阶段,data 以及 el 中的东西都已经被更新渲染到页面上了,也就是用户看到的页面,在这个函数执行完毕之后就代表整个初始渲染都加载完毕了,在这个函数是实例创建期间最后一个生命周期函数。如果想要在这个期间获取到 dom 元素的话,在上面的钩子函数中可以加 vm.$nextTick()函数表示 dom 渲染完毕之后的回调 ,这个回调函数也是发生在 mounted 挂载后前所调用的回调函数。
- beforeUpdate(更新前)
msp; 这个期间的钩子表示,数据发生改变的但是 dom 元素还没有改变的期间,这个期间 data 已经被改变了,但是 dom 元素还没有被更新。
- Update(更新后)
这个顾名思义就是发生在虚拟 dom 已经替换掉页面中元素后执行的钩子,表明虚拟 dom 以及数据都已经更新完毕。
- beforedestroy(销毁前)
这个表明在实例销毁前仍然可以使用整个 vue 实例对象,在这个阶段可以销毁定时器等一些操作在销毁后前想要做的最终操作。
- destroy(销毁后)
组件以及整个实例被销毁后触发,这时整个 vue 生命周期结束,vue 实例解除对 dom 的观察以及对数据的绑定,这时候改变数据跟 dom 都没有效果,但是被最终操作后的 dom 结构树依旧存在在页面中。
9. window 常见的三个弹窗的类型以及他们的作用?
- alert()弹出一个带有确定按钮的确定框。
- comfirm()弹出一个带有确定以及取消按钮的弹出框。
- prompt() 弹出一个带有输入框的弹出窗口。
10. $.ajax 请求中常用的一些参数以及参数作用?
- data: 请求的数据。
- datatype : 期望的服务器返回的数据类型。
- type : 请求类型。
- contentType : 发送数据的数据类型。
- success : 成功的回调。
- erro : 失败的回调。
- url : 请求的地址。
- async : 请求的方式是否是异步。
11. 前置守卫,路由独享守卫,组件内守卫的以及生命周期函数的执行顺序有啥区别?(或者守卫导航解析流程)
- 导航被触发。
- 在失活的组件里面调用 beforeRouteleave 守卫。(也就相当于是,在一个路由中离开去另一个路由前,调用离开前守卫的那个组件离开守卫)。
- 调用全局的 beforeEach 守卫。
- 之后调用重用组件的 beforeUpdate 守卫。ps:也就是调用完全局守卫之后,如果存在组件 beforeUpdate 守卫就会首先调用这个守卫。
- 之后调用路由独享守卫 beforeEnter。
- 之后解析异步路由组件。
- 解析完成之后,如果存在组件内守卫,这时才会调用第一个 beforeRouteEnter 守卫。
- 调用全局的 beforeResolve 守卫(又称:解析守卫)。ps:他的作用类似于 beforeEach 全局守卫,区别是它是发生在导航被确认之前的,这个是发生在异步路由以及组件守卫都已经被解析确认完毕之后才会触发。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 Dom 更新。
- 调用组件 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入进去。
追问: 如果加上生命周期,他们与守卫之间的执行顺序是什么样的?
首先:如果是存在上个 url 跳转到另一个 url 的情况,前面会先触发 beforeRouteLeave 守卫。
- 导航前置守卫: beforeEach
- 如果存在组件复用会先触发组件 beforeUpdate 守卫。
- 路由独享守卫:befroeEnter
- 组件内部守卫: beforeRouteEnter
- 导航解析守卫: beforeResolve
- 导航后置守卫: afterEach
- 组件钩子: beforeCreate
- 组件钩子: created
- 组件钩子: beforeMount
- deactivated: 离开缓存组件 a,或者触发 a 的 beforeDestroy 和 destroyed 组件销毁钩子。
- 组件钩子: mounted 访问跟操作 DOM
- 执行 beforeRouteEnter 回调的函数 next()。
12. computed 支持异步,watch 不支持异步。mutition 与 action 区别 也是一个不支持异步 一个支持异步。
13. OSI 模型有那些层? TCP/UDP/HTTP 分别在那些层?
自底向上有:
物理层······· 二进制在物理媒体上传输数据 (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)
14. 正向代理,与反向代理的区别?
15. 深拷贝与浅拷贝的区别,如何实现深拷贝与浅拷贝?
浅拷贝与深拷贝都是对于引用类型来说的,浅拷贝就是复制对象的引用,浅拷贝如果改变了复制对象的值,那么其源对象的值也会发生改变。,深拷贝就是对象的彻底拷贝,不值拷贝你用类型,也复制了值。只要进行深拷贝就是代表两个对象之间没有了联系。
深拷贝,递归的拷贝:
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
}
简单的深克隆 JSON 方式:
let Newtarget = JSON.parser(JSON.stringify(target))
// 这种是简单的深拷贝 但是不能拷贝,function 跟 undefined 类型的值。
16. 用 json 深拷贝有什么问题
json 进行深拷贝,不能拷贝 function,跟 undefined。
17. promise
- 主要用于异步计算
- 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
- 可以在对象之间传递和操作 promise,帮助我们处理队列
18. 内存泄漏
1. 什么是内存泄漏?
- 内存泄漏是指程序中分配的内存由于某种原因没有释放成功或者无法释放,导致程序的运行速度减慢等造成严重的卡死效果,内存泄漏是很常见的现象。
2. 内存泄漏的原因
- 一种是闭包造成的内存泄漏,其内部变量如果访问外部函数的变量,就会导致闭包的产生,会导致该变量在引用上一直是 1,会导致永远无法被垃圾回收,垃圾回收的机制是:标记计数法,跟引用计数法,在浏览器中一般是使用引用计数法。
- 意料之外的全局变量, 比如在非严格模式下在函数中不进行 var 变量,直接写一个变量名赋值,那么该变量就会被变量声明,也会造成内存泄露的问题。
- 脱离 DOM 的引用,同样如果 dom 元素存在树这种,另一个在字典中。将来你决定删除这些行的时候,需要把两个引用都同时清除。
19. 查看页面中内存泄漏的方法
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 为正数,则表示创建了闭包函数,如果多个快照中都没有变负数,则表示没有销毁闭包
20. react 生命周期
21. react 销毁的钩子函数有哪些?
22. 性能优化 react
23. react 减少请求次数,实现方式?
24. react 组件传参
25. 解决浏览器缓存
因为浏览器存在缓存机制,而且浏览器的缓存机制是为了防止用户想服务器多次发送相同的请求,机制原理是,当浏览器在第一次访问网站之后会生成一份缓存文件,如果下次访问的时候,文件的路径跟缓存中路径存在重复的情况他就不会重复想服务器发送请求,会从缓存中读取请求。这种机制有优缺点,优点:可以减轻服务器压力 ,提升下次打开网站的时候用户体验。缺点:比如在做验证码功能的时候你需要穿一个参数不停的去改变路径才可以使验证码每次点击都会被刷新。或者在引用 js
等 css 脚本的时候。添加一个版本号。
26. 前端做后台管理遇到问题?
- 配置权限的配置问题。
- 配置跨域代理,解决遇到跨域请求的问题。
27. vue 和 jquery 区别
- vue 是一个框架,jq 是一个类库。
- vue 是数据驱动,jq 一般要操作 dom 元素
- vue 能使前端项目变得更工程化,具有跨平台的特性。
28. 单页面应用
- 单页面应用就是只有一个总的 html 文件,在页面加载的时候只会向服务器发送一次请求。
- 单页面应用的特点,通过把整个项目进行模块化拆分,把一个个的模块中所包含的 js,css 跟 html 一起拆分成小模块进行开发,利于项目的维护,跟模块的重新利用,可以减轻代码负担优化项目流程。
- 拆分后加载次数比较少,而且通过路由进行跳转的时候性能比较高,不会重复的向服务器端多次发送请求。减轻服务器的压力。
29. 前端插件有哪些?
- cookie.js
- axios.js
- lodashi
- swiper
- jquey
- npm
- webpack
- gulp
- git
- sass
- less
- prerrtic
- eslint
- bable
30. 数组采用的方法
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.
31. 普通函数箭头函数
- 普通函数有 this 指向,在非严格模式下。
- 箭头函数在任何情况下没有 this 指向。
32. 正则把字符串中的空格替换?
33. for each for of
34. 手动写倒计时
35. 动态引入 js 文件
36. 前端缓存机制?
37. computed watch
37. 手动封装一个 promiseAll 方法
// 定义一个 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'
}) */
38. 如何把伪数组变成真数组?
arr.form() 把伪数组变成真数组。
39. 怎么取到数组的最小值?
sort 排序 a-b 取第一位 。升序是 b-a 取最后一位
40.JavaScript 是一个弱类型语言他的特点?
优点:弱类型使用简单,更灵活多变。
缺点:在代码的上线稳重,可能会进行隐式类型转换,会稍微损耗性能,可能不符合程序的本意。
41. 如何把伪数组变成真数组?
arr.from() 把伪数组变成真数组并进行浅拷贝类的实例。
42. C++跟 js 有什么区别?
- C++是静态语言,js 是动态语言。
- C++是编译型语言,js 是解释型语言。
- C++有指针,js 无指针。
- js 是函数式编程语言,C++不是
- C++的继承是基于类的,js 的继承基于原型
- js 的一个重要特性是闭包(当前作用域可以访问并保存外部作用域的变量)
- js 可以显示的设置上下文
43. 事件传播流程,传播流程的那几个阶段?
• 捕获阶段:事件对象从目标的祖先节点 Window 开始传播直至目标。
• 目标阶段:事件对象传递到事件目标。如果事件的 type 属性表明后面不会进行冒泡操作,那么事件到此就结束了。
• 冒泡阶段:事件对象以一个相反的方向进行传递,从目标开始,到 Window 对象结束。
44. jquery 的事件都有什么,然后 onclick 跟 addeventlistener 的区别?
45. 数组随机取一个数。
46. 取随机十个不重复的数。
47. 什么是二分法?
48. display 的常见属性值?
49. display:none 跟 visbaty:hidden 的区别?
50. css 如何写一个半圆形?
51. 如何让背景图铺满整个屏幕?
52. 如何实现一个元素的旋转?
53. 常见的浏览器内核?
54. css 权重选择器的规则?
55. 图片圆角,border 0 跟 border:none 的区别?
56. es6 的新增语法?
57. 箭头函数,跟普通函数的区别?
58. 图片懒加载
59. 鼠标一上去有一个提示效果?
60. 加载完成之后会触发那个事件?资源文件加载完成之后触发的事件?
61. Set 对象去重,如何实现一个冒泡排序?
62. MVC,跟 MVVM 的区别?
63. http 跟 https 的区别?
64. js 进行编码的方法?
65. 如果有一个非常长的字符串,怎么过滤出某些字符串?
66. 删除对象属性?
使用 delete 删除对象属性。
67. localstroge 跟 seesion 跟 cookie 的区别?
68. Es6 怎么实现继承?promise 有何特点?
69. 预编译五个步骤?Es6 导入导出跟 Es5 导入导出不同?
70. 如何实现圣杯布局,跟双飞翼布局?
71. target 跟 current target 区别?
72. 怎么实现,实时获取服务端实现的数据?
- 轮询
- 服务器实现 socket 连接,通过控制台使用命令更新数据。
- 通过数据库服务器的 trigger 机制。得到变化的数据。然后定制检查数据库,看数据是否有变化。
73. 怎么判断两个对象属性跟属性值相等让他两个相等?
- 通过 json.stringify 转换成字符串然后在判断两个字符串是否相等。
74. 设计模式有哪些?以及他们的作用。
75. 常见的排序方式?以及排序算法?
76. 什么是 SEO 优化?
全称:Search English Optimization,搜索引擎优化。自从有了搜索引擎,SEO 便诞生了。
存在的意义:为了提升网页在搜索引擎自然搜索结果中的收录数量以及排序位置而做的优化行为。简言之,就是希望百度等搜索引擎能多多我们收录精心制作后的网站,并且在别人访问时网站能排在前面。
分类:白帽 SEO 和黑帽 SEO。白帽 SEO,起到了改良和规范网站设计的作用,使网站对搜索引擎和用户更加友好,并且网站也能从搜索引擎中获取合理的流量,这是搜索引擎鼓励和支持的。黑帽 SEO,利用和放大搜索引擎政策缺陷来获取更多用户的访问量,这类行为大多是欺骗搜索引擎,一般搜索引擎公司是不支持与鼓励的。本文针对白帽 SEO,那么白帽 SEO 能做什么呢?
- 对网站的标题、关键字、描述精心设置,反映网站的定位,让搜索引擎明白网站是做什么的;
- 网站内容优化:内容与关键字的对应,增加关键字的密度;
- 在网站上合理设置 Robot.txt 文件;
- 生成针对搜索引擎友好的网站地图;
- 增加外部链接,到各个网站上宣传;
通过网站的结构布局设计和网页代码优化,使前端页面既能让浏览器用户能够看懂,也能让“蜘蛛”看懂。
(1) 网站结构布局优化:尽量简单、开门见山,提倡扁平化结构。
一般而言,建立的网站结构层次越少,越容易被“蜘蛛”抓取,也就容易被收录。一般中小型网站目录结构超过三级,“蜘蛛”便不愿意往下爬,“万一天黑迷路了怎么办”。并且根据相关调查:访客如果经过跳转 3 次还没找到需要的信息,很可能离开。因此,三层目录结构也是体验的需要。为此我们需要做到:
- 控制首页链接数量
网站首页是权重最高的地方,如果首页链接太少,没有“桥”,“蜘蛛”不能继续往下爬到内页,直接影响网站收录数量。但是首页链接也不能太多,一旦太多,没有实质性的链接,很容易影响用户体验,也会降低网站首页的权重,收录效果也不好。
因此对于中小型企业网站,建议首页链接在 100 个以内,链接的性质可以包含页面导航、底部导航、锚文字链接等等,注意链接要建立在用户的良好体验和引导用户获取信息的基础之上。
2.扁平化的目录层次,尽量让“蜘蛛”只要跳转 3 次,就能到达网站内的任何一个内页。扁平化的目录结构,比如:“植物”–> “水果” –> “苹果”、“桔子”、“香蕉”,通过 3 级就能找到香蕉了。
3.导航优化
导航应该尽量采用文字方式,也可以搭配图片导航,但是图片代码一定要进行优化,<img 标签必须添加“alt”和“title”属性,告诉搜索引擎导航的定位,做到即使图片未能正常显示时,用户也能看到提示文字。
其次,在每一个网页上应该加上面包屑导航,好处:从用户体验方面来说,可以让用户了解当前所处的位置以及当前页面在整个网站中的位置,帮助用户很快了解网站组织形式,从而形成更好的位置感,同时提供了返回各个页面的接口,方便用户操作;对“蜘蛛”而言,能够清楚的了解网站结构,同时还增加了大量的内部链接,方便抓取,降低跳出率。
- 网站的结构布局–不可忽略的细节
1)页面头部:logo 及主导航,以及用户的信息。
2)页面主体:左边正文,包括面包屑导航及正文;右边放热门文章及相关文章,好处:留住访客,让访客多停留,对“蜘蛛”而言,这些文章属于相关链接,增强了页面相关性,也能增强页面的权重。
3)页面底部:版权信息和友情链接。
特别注意:分页导航写法,推荐写法:“首页 1 2 3 4 5 6 7 8 9 下拉框”,这样“蜘蛛”能够根据相应页码直接跳转,下拉框直接选择页面跳转。而下面的写法是不推荐的,“首页 下一页 尾页”,特别是当分页数量特别多时,“蜘蛛”需要经过很多次往下爬,才能抓取,会很累、会容易放弃。
5.控制页面的大小,减少 http 请求,提高网站的加载速度。
一个页面最好不要超过 100k,太大,页面加载速度慢。当速度很慢时,用户体验不好,留不住访客,并且一旦超时,“蜘蛛”也会离开。
(2) 网页代码优化
1.
标题:只强调重点即可,尽量把重要的关键词放在前面,关键词不要重复出现,尽量做到每个页面的<title>标题中不要设置相同的内容。
2.标签:关键词,列举出几个页面的重要关键字即可,切记过分堆砌。
3.标签:网页描述,需要高度概括网页内容,切记不能太长,过分堆砌关键词,每个页面也要有所不同。
4.中的标签:尽量让代码语义化,在适当的位置使用适当的标签,用正确的标签做正确的事。让阅读源码者和“蜘蛛”都一目了然。比如:h1-h6 是用于标题类的,
标签是用来设置页面主导航的等。
5.标签:页内链接,要加“title” 属性加以说明,让访客和 “蜘蛛” 知道。而外部链接,链接到其他网站的,则需要加上 el="nofollow"属性, 告诉 “蜘蛛” 不要爬,因为一旦“蜘蛛”爬了外部链接之后,就不会再回来了。
6.正文标题要用
标签:“蜘蛛” 认为它最重要,若不喜欢
的默认样式可以通过 CSS 设置。尽量做到正文标题用
标签,副标题用
标签, 而其它地方不应该随便乱用 h 标题标签。
7.
标签:只用于文本内容的换行,比如:
第一行文字内容
第二行文字内容
第三行文字内容
8.表格应该使用表格标题标签
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 代码之后。
77. vue 中的 KEY 以及为何不用索引当 KEY。
78.嵌套组件的生命周期执行顺序是如何的?
先执行父组件 beforecreate 在执行 created 之后执行 子组件的 beforecreate 一直到 mounted 之后再执行父组件的 beforemount 跟 mounted。