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(',')
}
複製代碼
這是一個投機取巧的方法(面試寫個這個也湊合吧),若是有興趣能夠搜索一下其餘實現方法