# 2020 / 3 / 17
自结题
# 1 / 写一个traverse函数,输出所有页面宽度和高度大于50像素的节点
function traverse(){
var arr = []
var elements = []
if(document.all){
elements = document.all
}else{
elements = document.getElementsByTagName('*')
}
for(var i = 0; i < elements.length; i++){
var ele = elements[i]
var width = parseFloat(ele.style.width) || ele.offsetWidth
var height = parseFloat(ele.style.height) || ele.offsetWidth
if(width > 50 && height > 50){
arr.push(elements[i].tagName)
}
}
return arr
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 2 / 请写一个表格以及对应的css,使表格奇数行为白色背景,偶数行为灰色背景,鼠标移上去时为黄色背景
<table class='table'>
<tr><td>第一行</td></tr>
<tr><td>第一行</td></tr>
<tr><td>第一行</td></tr>
<tr><td>第一行</td></tr>
</table>
1
2
3
4
5
6
2
3
4
5
6
.table tr:nth-child(odd){
background-color:white;
}
.table tr:nth-child(even){
background-color:gray;
}
.table tr:hover{
background-color:yellow;
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3 / 写一个求和的函数sum,达到下面的效果
# Demo
// Should equal 15
sum(1,2,3,4,5)
// Should equal 0
sum(5, null, -5)
// Should equal 9
sum('1.0', false, 1, true, 'A', 1, 'B', 1, 'C', 1, 'D', 1, 'E', 1, 'F', 1, 'G', 1)
// Should equal 0.3 not 0.30000000000004
sum(0.1, 0.2)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
答案:
function sum(){
var args = [].slice.call(arguments)
return args.reduce((result, item) => {
return result += parseFloat(item) || 0
},0).toFixed(3) * 1000 / 1000
}
1
2
3
4
5
6
2
3
4
5
6
# 4 / 删除给定数组中的第二项和第三项,并且在新得到的新数组中第二项后面添加一个新值
var arr = ['a','b','c','d','e']
var newArr = arr.splice(1,2,'newValue')
1
2
2
# 5 / 请实现一个斐波那契(fibonacci)函数,要求其参数和返回值如下
# @desc:fibonacci
# @params:count{Number}
# @return:result{Number}
第count个fibonacci值,计数从0开始
fibonacci数列为:[1,1,2,3,5,8,13,21,34,...]
1
2
3
4
5
6
2
3
4
5
6
function getNthFibonacci(count){
if(count <= 1) return 1
return getNthFibonacci(count-1) + getNthFibonacci(count-2)
}
1
2
3
4
5
2
3
4
5
# 5 / 填写内容让代码支持 a.name = 'name1'; b.name = 'name2'
function obj(name){
if(name){
this.name = name
}
}
obj.prototype.name = 'name2'
var a = obj('name1')
var b = new obj
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 6 / 你了解Http状态码吗,请随便介绍一下
- 100 Countinue 继续,一般在发送post请求时,已发送了http header之后服务器将返回此信息,表示确认,之后发送具体参数信息
- 200 OK 正常返回信息
- 201 Created 请求成功并且服务器创建了新的资源
- 202 Accepted 服务器已接受请求,但尚未处理
- 301 Moved Permanently 永久重定向请求的网页已永久移动到新位置
- 302 Found 临时重定向
- 303 See Other 临时重定向,且总是使用GET请求新的URI
- 304 Not Modified 自从上次请求后,请求的网页未修改过
- 400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求
- 401 Unauthorized 请求未授权
- 403 Forbidden 禁止访问
- 404 Not Found 找不到与URI相匹配的资源
- 500 Internal Server Error 最常见的服务器端错误
- 503 Service Unavailable 服务器暂时无法处理请求(可能过载或维护)
# 7 / js 数组去重
Array.prototype.uniq = function(){
// 长度为1,则直接返回当前的拷贝
if(this.length <= 1) return this.slice(0)
var result = []
for(var i = 0; i < this.length; i++){
// isExist判断是否已经存在,true存在,false不存在
if(!isExist(result, this[i])){
result.push(this[i])
}
}
return result
// 定义 isExist 函数
function isExist(arr, item){
if(arr.length === 0) return false
var tmp
for(var i = 0; i < arr.length; i++){
tmp = arr[i]
if(tmp === item){
return true
}
// NaN 需要特殊处理
if(!item && !tmp && tmp !== undefined && item !== undefined && isNaN(tmp) && isNaN(item)){
return true
}
}
return false
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 8 / 说说对网站重构的理解
网站重构:在不改变外部行为的前提下,简化结构,添加可读性,而在网站前端保持一致的行为。也就是说在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI
对于传统的网站来说重构是:
- 表格布局改为 div + css
- 使网站前端兼容于现代浏览器
- 对于移动平台的优化
- 针对于SEO进行优化
- 深层次的网站重构应该考虑的方面
- 减少代码间的耦合
- 让代码保持弹性
- 严格按规范编写代码
- 设计可扩展的API
- 代替旧有的框架,语言
- 增强用户体验
- 压缩Js,css,image等前端资源
- 采用cdn来加速资源加载
- 对于Js Dom操作优化
# 9 / Js对象的深度克隆代码实现
function cloneDeep(obj){
var buf;
if(obj instanceof Array){
buf = [] // 创建一个空的数组
var i = obj.length
while(i--){
buf[i] = cloneDeep(obj[i])
}
return buf
}else if(obj instanceof Object){
buf = {}
for(var k in obj){
buf[k] = cloneDeep(obj[k])
}
return buf
}else{
return obj
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 10 / Ajax是什么? Ajax的交互模型?同步和异步的区别?如何解决跨域问题?
Ajax全称异步的Javascript和XML,是一种创建快速动态的技术,通过在后台与服务器进行少量数据交互,实现网页的异步更新,在不更新加载整个界面的情况下,实现网页的局部更新
Ajax的交互模型(Ajax的过程)
- 用户发出异步请求
- 创建XMLHttpRequest对象
- 可以设置Http请求的请求头
- 设置响应状态改变的事件回调函数(onreadystatuschange)
- 发送请求
- 获取异步调用返回的数据
- 使用Js和Dom进行局部解析
同步和异步的区别?
- 同步:脚本会停留并等待服务器返回数据后再继续执行
- 异步:脚本允许页面继续执行而不需等待服务器返回数据
跨域问题解决:
- 使用document.domain + iframe
- 使用window.name 利用同一页面下所有域名共享同一个name属性
- 使用flash
- 使用postMessage
- 使用jsonP(创建动态script)
# 11 / 事件、Ie与火狐的事件机制有什么区别?如何阻止冒泡
- 我们在网页中的某个操作(有的操作定义多个事件)。例如:点击一个按钮就会产生一个事件
- 事件处理机制:
- Ie是事件冒泡;firefox同时支持两种事件类型,即捕获型事件和冒泡型事件
- 阻止事件冒泡
- event.stopPropagation()
- 旧版ie:event.cancelBubble = true
# 12 / web应用从服务器主动推送Data到客户端都有哪些方式?
- html5 webSocket
- webSocket 通过 flash
<script>
标签的长时间连接- XHR长时间连接
# 13 / 写一个通用的事件侦听器函数
let eventListener = {
// 页面加载完成后
readyEvent:function(fn){
if(fn == null){
fn = document
}
var oldonload = window.onload
if(typeof window.onload != 'function'){
window.onload = fn
}else{
window.onload = function(){
oldonload()
fn()
}
}
}
// 绑定事件 ,参数:操作的元素,事件名称,事件处理函数
addEvent:function(element, type, handler){
if(element.addEventListener){
// 参数:事件类型,事件处理函数,是否捕获
element.addEventListener(type, handler, false)
}else if(element.attachEvent){
element.attachEvent('on'+type, function(){
handler.call(element)
})
}else{
element['on' + type] = handler
}
}
// 移除事件
removeEvent:function(element, type, handler){
if(element.removeEventListener){
element.removeEventListener(type, handler, false)
}else if(element.detachEvent){
element.detachEvent('on'+type, handler)
}else{
element['on' + type] = null
}
},
// 阻止事件(主要是事件冒泡,因为Ie不支持事件捕获)
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation()
}else{
event.cancelBubble = true
}
},
// 取消事件的默认行为
preventDefault:function(event){
if(event.prevenrDefault){
event.prevenrDefault()
}else{
event.returnValue = false
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 14 / eval作用是什么? 对它有什么建议?
- 它的功能是把对应的字符串解析成Js代码并运行
- 应该避免使用eval,不安全且非常耗性能
# 15 / 哪些地方会出现css阻塞,哪些地方会出现js阻塞?
Js的阻塞特性:所有浏览器在下载Js的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。为了提高用户体验,新一代浏览器都支持并行下载Js,但是Js下载仍然会阻塞其他资源的下载(例如图片,css文件等)
由于浏览器为了防止出现Js修改Dom树,需要重新构建Dom树的情况,所以就会阻塞其他的下载和呈现
嵌入Js会阻塞所有内容的呈现,而外部Js只会阻塞其后内容的显示,2种方式都会阻塞其后资源的下载,也就是外部样式不会阻塞外部脚本的加载,但会阻塞外部脚本的执行
那Css怎么会阻塞加载?css本来是可以并行下载的,在什么情况下会出现阻塞加载?当Css后面跟着嵌入的Js时,该Css就会出现阻塞后面资源下载的情况,而当把嵌入的Js放到Css前面,就不会出现阻塞的情况了
根本原因:因为浏览器会维持Html中Css和Js的顺序,样式表必须在嵌入的Js执行先加载,解析完,而嵌入的Js会阻塞后面的资源加载,所以就会出现Css阻塞下载的情况
那么嵌入的Js应该放在那?
- 放在底部,虽然放在底部照样会阻塞所有呈现
- 如果嵌入Js放在head中,请把嵌入Js放在css头部
- 使用 defer(延迟加载)
- 不要在嵌入的Js中调用运行时间较长的函数,如果一定要用,可以用setTimeout来调用
# 16 / GET与POST区别? 何时使用POST?
- GET:一般用于信息获取,使用URL来传递参数,对所发送信息的数量也有限制,一般在2000个字符
- POST:一般用于修改服务器上的资源,对所发送的信息没有限制
- GET方式需要使用 request.queryString 来取得变量的值
- POST方式需要使用 request.from 来获取变量的值
即 GET 通过地址栏来传值,而 POST 通过提交表单来传值
在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST没有数据量限制)
- 发送包含位置字符的用户输入时,POST 比 GET 更稳定可靠