- JS的內存泄露,無怪乎就是從DOM中remove了元素,但是依然有變量或者對象引用了該DOM對象。然后內存中無法刪除。使得瀏覽器的內存占用居高不下。這種內存占用,隨著瀏覽器的刷新,會自動釋放。
- 而另外一種情況,就是循環引用,一個DOM對象和JS對象之間互相引用,這樣造成的情況更嚴重一些,即使刷新,內存也不會減少。這就是嚴格意義上說的內存泄露了。
所以在平時實際應用中, 我們經常需要給元素緩存一些數據,并且這些數據往往和DOM元素緊密相關。由于DOM元素(節點)也是對象, 所以我們可以直接擴展DOM元素的屬性,但是如果給DOM元素添加自定義的屬性和過多的數據可能會引起內存泄漏,所以應該要盡量避免這樣做。 因此更好的解決方法是使用一種低耦合的方式讓DOM和緩存數據能夠聯系起來。
jQuery引入緩存的作用
- 允許我們在DOM元素上附加任意類型的數據,避免了循環引用的內存泄漏風險
- 用于存儲跟dom節點相關的數據,包括事件,動畫等
- 一種低耦合的方式讓DOM和緩存數據能夠聯系起來
jQuery緩存系統的真正魅力在于其內部應用中,動畫、事件等都有用到這個緩存系統。試想如果動畫的隊列都存儲到各DOM元素的自定義屬性中,這樣雖然可以方便的訪問隊列數據,但也同時帶來了隱患。如果給DOM元素添加自定義的屬性和過多的數據可能會引起內存泄漏,所以要盡量避免這么干。
數據緩存接口
jQuery.data( element, key, value )
在jQuery的官方文檔中,提示用戶這是一個低級的方法,應該用.data()方法來代替。$.data( element, key, value )可以對DOM元素附加任何類型的數據,但應避免循環引用而導致的內存泄漏問題
- 看jQuery.data(element,[key],[value]),每一個element都會有自己的一個{key:value}對象保存著數據,所以新建的對象就算有key相同它也不會覆蓋原來存在的對象key所對應的value,因為新對象保存是是在另一個{key:value}對象中
- $("div").data("a","aaaa") 它是把數據綁定每一個匹配div節點的元素上
Deferred對象存在的意義在哪里?
從我角度來說,對于開發者
1:代碼可讀性,扁平化結構
2:讓支離破碎的代碼結構,繼續保存線性的代碼邏輯,也就是異步代碼轉為同步
3: 從抽線的角度,提供了一個抽象的非阻塞的解決方案(如 Ajax 請求的響應),它創建一個 “promise” 對象,其目的是在未來某個時間點返回一個響應。
deferreds 可以理解為表示需要長時間才能完成的耗時操作的一種方式,相比于阻塞式函數它們是異步的,而不是阻塞應用程序等待其完成然后返回結果。 deferred對 象會立即返回,然后你可以把回調函數綁定到deferred對象上,它們會在異步處理完成后被調用。
所以,總的來講Deferred通過一組 API 來規范化異步操作,這樣也能夠讓異步操作的流程控制更加容易
1、顯而易見Deferred是個工廠類,返回的是內部構建的deferred對象
2、tuples 創建三個$.Callbacks對象,分別表示成功,失敗,處理中三種狀態
3、創建了一個promise對象,具有state、always、then、primise方法
4、擴展primise對象生成最終的Deferred對象,返回該對象
jQuery的事件優化
.bind()、.live() .on()和.delegate()
不管你用的是(click / bind / delegate)之中那個方法,最終都是jQuery底層都是調用on方法來完成最終的事件綁定
因此從某種角度來講除了在書寫的方便程度及習慣上挑選,不如直接都采用on方法來的痛快和直接
所以在新版的API中都這么寫到:
.on()方法事件處理程序到當前選定的jQuery對象中的元素。在jQuery 1.7中,.on()方法 提供綁定事件處理的所有功能
除了性能的差異,通過委托的事件還能很友好的支持動態綁定
只要on的delegate對象是HTML頁面原有的元素,由于是事件的觸發是通過Javascript的事件冒泡機制來監測,所以對于所有子元素(包括后期通過JS生成的元素)所有的事件監測均能有效,且由于不用對多個元素進行事件綁定,能夠有效的節省內存的損耗。
jsonp的實現與原理
ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態添加<script>標簽來調用服務器提供的js腳本
jsonp核心就是:允許用戶傳遞一個callback參數給服務端,然后服務端返回數據時會將這個callback參數作為函數名來包裹住JSON數據,這樣客戶端就可以隨意定制自己的函數來自動處理返回數據了。
客戶端:
$.ajax({
async: false, // 同步加載數據,即等到ajax執行完畢再接著執行下面的語句
url: 'http://192.168.1.114/yii/demos/test.php', //不同的域
type: 'GET', // jsonp模式只有GET是合法的
data: {
'action': 'aaron'
}, // 預傳參的數組
dataType: 'jsonp', // 數據類型
jsonp: 'backfunc', // 指定回調函數名,與服務器端接收的一致,并回傳回來
success: function(json) {
console.log(json);
}
})
php服務端:
<?php
$act = trim($_GET['action']);
if($act == 'aaron' ){
echo trim($_GET['backfunc']).'('. json_encode(array('status'=>1,'info'=>'OK')) .')';
}
?>
出于同源策略考慮,存在跨域問題,所以ajax內部的處理總的來分2大塊
- 基于XMLHttpRequest的ajax請求
- 基于script的jsonp跨域請求