- 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跨域请求
网友评论