cookie:
客戶永久性或者暫時性儲存的少量狀態數據。cookie隨着網頁被服務器發送給客戶,客戶在本地將他們儲存起來。以後當客戶請求統一網頁或者與之相關的網頁時,他可以把相關的cookie傳回服務器,服務器能夠利用這些cookie的值來改變發送回客戶的內容。 cookie使網頁或者網站能夠記住有關客戶的一些信息。
全局變量:全局對象
在js解析開始的時候,在執行任何js代碼前,創建一個全局對象,這個對象的屬性就是js程序的全局變量。當聲明一個js的全局變量時,實際上所作的是定義了那個全局對象的一個屬性。
局部變量:調用對象
局部變量是局部對象的屬性,這個對象稱之爲調用對象。在執行一個函數時,函數的參數和局部變量作爲調用對象的屬性而存儲。
當函數引用一個變量時,首先檢查的是調用對象(局部作用域),其次才檢查全局對象(全局作用域)。
外層作用域不能調用內層作用域的變量。
垃圾回收機制——無用存儲單元收集
使用的算法是*“標記和清除算法”*
一個標記和清除的無用存儲單元回收器會週期性的便利JS環境的所有變量的列表,並給這些變量所引用的值做標記。若被引用的值是對象或者數組,那麼對象的屬性或者數組的元素就會被遞歸的坐上標記。通過遞歸的遍歷所有值得樹或者圖,無用存儲單元收集器就能夠找到並標記讓那仍舊使用的每個值。那些沒被標記的值就是無用的存儲單元。
之後進行清除,遍歷環境中所有值得列表,釋放哪些沒有被標記的值。
跨瀏覽器事件兼容
let EventUtil = {
addHandler: function(element, type, handler) {
if(element.addEventListener) {
element.addEventListener(type, handler, false) // false指在冒泡階段處理程序 true則爲在補貨階段處理程序。 可以省略
} else if(element.attachEvent) { // IE 均爲在冒泡階段處理程序
element.attachEvent('on'+ type, handler)
} else {
element['on' + type] = handler
}
},
removeHandler: function(element, type, handler) {
if(element.removeEventListener) {
element.removeEventListener(type, handler, false) // false指在冒泡階段處理程序 true則爲在補貨階段處理程序。 可以省略
} else if(element.detachEvent) { // IE 均爲在冒泡階段處理程序
element.detachEvent('on'+ type, handler)
} else {
element['on' + type] = null
}
},
getEvent: function(event) {
return event ? event : window.event
},
getTarget: function(event) {
return event.target || event.srcElement
},
preventDefault: function(event) {
if(event.preventDefault) {
event.preventDefault()
} else {
event.returnValue = false
}
},
// 取消事件捕獲 和冒泡
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation
} else {
event.cancelBubble = true
}
},
}
函數綁定
行數綁定要創建一個函數,可以在特定的this環境中以指定參數調用另一個函數。 該技巧常常和回調函數與事件處理程序一起使用。一遍在將函數作爲變量傳遞的同事保留代碼執行環境。
function bind (fn, context){
return function(){
fn.apply(context, arguments)
}
}
var handle = {
msg: 'hello',
method(event) {
alert(this.msg)
}
}
btn.addeventListener('click', bind(handle.method, handle))
// js原生:
btn.addeventListener('click', handle.method.bind(handle)) // fn.bind(this)
</script>
柯里化
使用閉包返回一個函數,將其他參數全部傳入到該函數中
function curry(fn) {
let args = Array.protopy.slice.call(arguments, 1)
return function () {
let innetArgs = Array.protopy.slice.call(arguments)
let finalArgs = args.concat(finalArgs)
return fn.apply(null, finalArgs)
}
}
截取外層函數的第一個參數,因爲這個參數是一個回調函數。將內層函數的參數傳遞給該回調函數。
重複定時器
定時器:在一定時間後插入到隊列,而不是在一定時間後執行
setInterval() 有兩個問題:
1 某些間隔會被跳過
2 多個定時器的代碼執行間的間隔可能會比設定值小
==> 用setTimeout()鏈式寫法修改
setTimeout(function(){
//....
setTimeout(arguments.callee, interval)
}, interval)
數組分塊
當某個函數要花較長時間完成時,可以將任務分割成一系列的小任務分開完成
該方法接受三個參數:要處理的項目的數組,用於處理項目的函數,以及可選的運行該函數的環境
function chunk(array, process, context){
setTimeout(function() {
let item = array.shift()
process.call(context, item)
if (array.length > 0) {
setTimeout(arguments.callee, interval)
}
}, interval)
}
節流函數
某些代碼不可以在沒有間斷的情況下連續重複執行
function throttle (method, context) {
clearTimeout(method.tId)
method.tId = setTimeout(function(){
method.call(context)
}, interval)
}
至少等interval纔能有效的執行函數
setTimeout的使用環境始終是window
性能的提升
1.解耦應用邏輯與事件處理程序
2.尊重對象的所有權,不修改不是有自己創建的對象
避免全局變量
避免與null比較, 用instanceof / typeof
使用常量
3.作用域:
避免全局查找,將在一個函數中多次使用到的全局變量對象村委局部變量
避免with語句
4.使用變量和數組比直接訪問對象上的屬性更有效率
=> 多次使用的對象屬性,存儲爲局部變量
5.減值迭代 簡化終止條件, 簡化循環體, 使用後測序循環(do-while)
6.減少語句數量,
一個var 一次性聲明多個變量,逗號隔開
使用數組和對象字面量