1** 信息,服务器收到请求,须要请求者继续执行操做(101,升级为websocket协议)
2** 成功,操做被成功接收并处理(206,部份内容,分段传输)
3** 重定向,须要进一步操做以完成请求(301,302重定向;304命中缓存)
4** 客户端错误,请求包含语法错误或没法完成请求(401,要求身份验证;403,服务器理解客服端需求,可是禁止访问)
5** 服务器错误,服务器在处理请求的过程当中发生了错误javascript
ajax不必定是异步的,能够经过open方法的第三个参数来配置(默认为true,异步)
css
状态码:html
0 - (未初始化)尚未调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,能够在客户端调用了
前端
ajax是一种和后台通讯的标准。全称是Asynchronous Javascript And XML(异步javascript和XML)。java
优点:react
劣势:webpack
注意的问题:es6
1.toString() //Uncaught SyntaxError: Invalid or unexpected token
true.toString() //"true"
[].toString() //""
{}.toString() //Uncaught SyntaxError: Unexpected token .
null.toString() //Uncaught TypeError: Cannot read property 'toString' of null
undefined.toString() //Uncaught TypeError: Cannot read property 'toString' of undefined
NaN.toString() //"NaN"
复制代码
这些须要刻意背一下,其中1和{}是语法错误。null和undefined是由于没有toString
方法,可使用call
来借用(想详细了解,能够到评论区看我如何被骂的):web
1..toString() //"1"
(1).toString() //"1"
Number(1).toString() //"1"
({}).toString() //[object Object]
Object.prototype.toString.call(null) //[object Null]
Object.prototype.toString.call(undefined) //[object Undefined]
复制代码
reflow翻译为回流,指的是页面再次构建render树。每一个页面至少发生一次回流,就是第一次加载页面的时候面试
此外,当页面中有任何改变可能形成文档结构发生改变(即元素间的相对或绝对位置改变),都会发生reflow,常见的有:
repaint翻译为重绘,它能够类比为上面的第四步,根据render树绘制页面,它的性能损耗比回流要小。每次回流必定会发生重绘。此外,如下操做(不影响文档结构的操做,影响结构的会发生回流)也会发生重绘:
咱们不太容易精确知道哪些操做具体会形成哪些元素回流,不一样的浏览器都有不一样的实现。可是肯定是他们的的耗时是比较长的,由于涉及到大量的计算。
浏览器为了提高性能也对这个问题进行了优化。方案就是维护一个队列,把全部须要回流和重绘的操做都缓存起来,一段时间以后再统一执行。可是,有的时候咱们须要获取一些位置属性,当咱们一旦调用这些api的时候,浏览器不得不当即计算队列以保证提供的数据是准确的。例如如下操做:
//es6
' ab '.trim() //"ab"
//正则
' ab '.replace(/^\s*|\s*$/g,'') //"ab"
复制代码
function queryUrlParameter(str) {
let obj = {}
let reg = /([^?=&#]+)=([^?=&#]+)/g;
str.replace(reg, function () {
obj[arguments[1]] = arguments[2]
})
//若是加上hash
// reg = /#([^?&=#]+)/g
// if (reg.test(str)) {
// str.replace(reg, function () {
// obj.hash = arguments[1]
// })
// }
return obj
}
console.log(queryUrlParameter('http://www.baidu.com?a=1&b=2#12222')) //{ a: '1', b: '2'}
复制代码
function clone(obj) {
if (obj == null || typeof obj !== 'object') return obj
let newObj = null
// 时间对象有特殊性
if (obj.constructor === Date) {
newObj = new obj.constructor(obj)
} else {
newObj = obj.constructor()
}
for (let key in Object.getOwnPropertyDescriptors(obj)) {
newObj[key] = clone(obj[key])
}
return newObj
}
复制代码
function deepCompare(a, b){
if(a === null
|| typeof a !== 'object'
|| b === null
|| typeof b !== 'object'){
return a === b
}
const propsA = Object.getOwnPropertyDescriptors(a)
const propsB = Object.getOwnPropertyDescriptors(b)
if(Object.keys(propsA).length !== Object.keys(propsB).length){
return false
}
return Object.keys(propsA).every( key => deepCompare(a[key], b[key]))
}
复制代码
function throttle(fn, delay) {
delay = delay || 50
let statTime = 0
return function () {
statTime === 0 && fn.apply(this, arguments)
let currentTime = new Date()
if (currentTime - statTime > delay) {
fn.apply(this, arguments)
statTime = currentTime
}
}
}
let throttleFn = throttle(fn)
throttleFn()//只会执行一次
throttleFn()
throttleFn()
throttleFn()
复制代码
function debounce(fn, delay) {
delay = delay || 50
let timer = null
return function () {
let self = this
clearTimeout(timer)
timer = setTimeout(fn.bind(self, arguments), delay);
}
}
复制代码
Function.prototype._bind = function (context) {
let self = this
let args_1 = [].prototype.slice.call(arguments, 1)
return function () {
let args_2 = [].prototype.slice.call(arguments)
let args = args_1.concat(args_2)
return self.apply(context, args)
}
}
复制代码
这只是对bind的一种简单实现,若是有兴趣了解更多能够参考Javascript中bind()方法的使用与实现
function (ary) {
return ary.toString().split(',')
}
复制代码
这是一个投机取巧的方法(面试写个这个也凑合吧),若是有兴趣能够搜索一下其余实现方法