事件委托,冒泡,捕获,深度克隆

1. 事件冒泡 事件捕获 

监听者模式->事件流->addEventLisnter/removeEventLisenter->attachEvent/detachEvent->冒泡和捕获的区别->事件委托

早起的事件是用来缓解服务器压力的一种手段,当发生特定交互的一瞬间,如click, mousemove, onkeydown等事件时,我们可以通过侦听器来监听事件,并作出反应,这种模式叫做监听者模式。

在dom文件生成的过程中,会产生一个dom树,当子元素的事件被触发之后,父元素和祖宗元素也会默认被触发。这时候就要依据冒泡或者捕获来判定触发顺序。

IE浏览器中,是由内向外依次传播,名为事件冒泡,网景提出的是从外向内触发,名为事件捕捉。现在的正常浏览器一般是支持捕获和冒泡,由addEventListener的第三个变量来判定。true为事件捕捉,false为事件冒泡。但如果第二个参数是匿名函数的话是无法用removeEventListner来取消事件监听的。此外,Jquery中的e.stopPropagation可以阻止冒泡,IE用cancelBubble。

利用冒泡/监听者模式的好处在于,例如一个ul里面有很多li,如果给每一个li绑定事件的话,如果动态生成新的li时必须再为其绑定事件,但是如果利用监听者模式,动态添加的li也会在冒泡后自动触发事件,因为事件被绑定在了监听者(父元素身上)。这个也用到了另外一种基于事件冒泡原理的思想叫做事件委托。由于安全方面的考虑,操作系统怕黑客通过浏览器恶意的做大量的运算或者小号内存,只会给浏览器分配少量内存。这时候过多的对象还有绑定事件会大大的影响浏览器的工作效率。这是我们可以通过前面提到的方法尽量再级别高的dom元素上绑定监听事件,以此来减少内存使用并提升性能。

focus blur change submit reset select事件不冒泡


2.深度克隆 

深克隆浅克隆区别 ->原始值和引用值->堆和栈的区别-> $.extend -> 递归实现深克隆 

深克隆浅克隆区别主要在于,如果说被克隆的对象中不包含引用值而全是原始值的话,深浅克隆无区别,而如果被克隆对象中包含引用值的话,浅克隆后的对象的引用值如果发生改变,被克隆的对象也会发生改变。而深克隆不会发生该问题,因为深克隆后被克隆对象的引用址和克隆着的引用值被存放在不同的内存地址里面。

JS中有五个原始值,分别是boolean, string, number, null, undefined。 引用值包括function和object,array和objct都包含在object里面。这里还有一个历史遗留的bug。null是一个原始值,并不是一个空对象,但是typeof null的结果是object。

这里我们要说一下堆和栈的区别,堆和栈的表层区别在于,栈(stack)先进后出,堆(heap)先进先出。栈由系统自动释放,是一块连续的内存区域,空间较小,但是响应速度较快,主要用于存放原始值,因为一般原始值有一个固定的大小,比较不容易overflow。而堆是用链表储存的一些列不相连的的地址,因为可存放空间较大,主要用来储存引用址,但是由于要在链表中查找所以速度稍微慢一些。

jquery中提供了一种方法,叫$.extend,第一个变量可以控制深克隆还是浅克隆,如果是深克隆为true,浅克隆为false,默认值为false。

function shallowCopy(obj){
 var newObj = {};
 for(var i in obj){
  newObj[i] = obj[i];
 } 
 return newObj
}
funciton deepCopy(obj, newObj){
    newObj = {};
    for(var i in obj){
        if(typeof obj[i]== 'object'){
            if(obj[i].constructor == {}){
                newObj[i] = {};
            }else{
                newObj[i] = [];
            }
            deepCopy(obj[i],newObj[i]);
        }else{
            newObj[i] = obj[i];
        }
    }
}

上面使用递归来实现的是克隆,在判定为引用值后用constructor来判定该对象是否为array,并向内递归直到找到没有引用值为止。



阅读更多

没有更多推荐了,返回首页