jQuery剥皮三- data、proxy、event

news/2024/11/8 11:56:19/

为什么80%的码农都做不了架构师?>>>   hot3.png

jquery1.4  jquery1.4下载

这里使用了 jQuery1.4,为什么使用 1.4 因为 1.4 很多特性没有添加分析起来相对容易。


这个 data 的实现是扩展在 jQuery 静态函数里面的,我们平常这样( $('#data').data('tudou', 'abc') )调用的是 jQuery 原型上的 data ,原型上面的 data 再调用下面 jQuery 静态的 data 方法实现。

jQuery.extend({cache: {},expando:expando,// The following elements throw uncatchable exceptions if you// attempt to add expando properties to them.noData: {"embed": true,"object": true,"applet": true},data: function( elem, name, data ) {// 不是正确的元素过滤掉if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {return;}elem = elem == window ?windowData :elem;var id = elem[ expando ], cache = jQuery.cache, thisCache;// Handle the case where there's no name immediately// 没有 data 名 且 也没有设置过 data 返回if ( !name && !id ) {return null;}// Compute a unique ID for the elementif ( !id ) { id = ++uuid;}// Avoid generating a new cache unless none exists and we// want to manipulate it.if ( typeof name === "object" ) {elem[ expando ] = id;// 如果传递过来的是对象,直接扩展到 cache 对象中thisCache = cache[ id ] = jQuery.extend(true, {}, name);} else if ( cache[ id ] ) {// 如果有存储过,则拿到以前的thisCache = cache[ id ];} else if ( typeof data === "undefined" ) {thisCache = emptyObject;} else {// 第一次存储,要新建一个空对象thisCache = cache[ id ] = {};}// Prevent overriding the named cache with undefined values// 把数据写入 cache 存储 根据uuidif ( data !== undefined ) {elem[ expando ] = id;thisCache[ name ] = data;}// 返回附加的数据return typeof name === "string" ? thisCache[ name ] : thisCache;},removeData: function( elem, name ) {if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {return;}elem = elem == window ?windowData :elem;var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];// If we want to remove a specific section of the element's dataif ( name ) {if ( thisCache ) {// Remove the section of cache datadelete thisCache[ name ];// If we've removed all the data, remove the element's cacheif ( jQuery.isEmptyObject(thisCache) ) {jQuery.removeData( elem );}}// Otherwise, we want to remove all of the element's data} else {// Clean up the element expandotry {delete elem[ expando ];} catch( e ) {// IE has trouble directly removing the expando// but it's ok with using removeAttributeif ( elem.removeAttribute ) {elem.removeAttribute( expando );}}// Completely remove the data cachedelete cache[ id ];}}
});


这个 data 的实现是在 jQuery 函数上创建了一个静态变量 cache 对象,key 就是 data 的 name, value 就是 data 的 value。如下图:

214745_48tr_568138.png

现在来看一张图,来观察 data 实现的方法

220447_3JyN_568138.png

实现方法就是 jQuery 在对元素操作的时候会赋值一个 "jQuery" + now() 时间戳的属性,其值是一个 uuid 唯一的数字,每次操作会加 1 ,然后在 jQuery 的 cache 的对象静态变量中根据这个 uuid 赋值一个 key 就像这样 {5:{}}。并且把你要加入的 data 放去这个 key 为 5 的对象中 {5:{tudou:"abc"}}。他们唯一关联的就是这个 uuid 。

看看 jQuery 的原型实现

jQuery.fn.extend({data: function( key, value ) {if ( typeof key === "undefined" && this.length ) {return jQuery.data( this[0] );} else if ( typeof key === "object" ) {// 对象直接进行 data 存储return this.each(function() {jQuery.data( this, key );});}var parts = key.split(".");parts[1] = parts[1] ? "." + parts[1] : "";// 如果只传 name 就是获取值if ( value === undefined ) {// 设置会触发 getData 自定义方法 他们都可以通过 bind 捕获var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);if ( data === undefined && this.length ) {data = jQuery.data( this[0], key );}return data === undefined && parts[1] ?this.data( parts[0] ) :data;} else {// 设置值会触发 setData 方法   他们都可以通过 bind 捕获return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {jQuery.data( this, key, value );});}},removeData: function( key ) {return this.each(function() {jQuery.removeData( this, key );});}
});

这里的实现就显得轻松许多了,只需要多 参数、获取/设置 值进行处理就可以了 ,然后去调用对应的 jQuery.data 方法去实现值的设置或者获取 

之前简单的模拟过一个  原理差不多是这样

proxy 比较简单,但是很容易晕的一个东西,给你来几个 proxy + 返回闭包 基本都会晕 :(

proxy: function( fn, proxy, thisObject ) {if ( arguments.length === 2 ) {if ( typeof proxy === "string" ) { // 第一种方式调用方式 $.proxy(obj, 'fn')thisObject = fn;fn = thisObject[ proxy ];proxy = undefined;} else if ( proxy && !jQuery.isFunction( proxy ) ) { // 第二种调用方式 $.proxy(obj.fn, obj)thisObject = proxy;proxy = undefined;}}if ( !proxy && fn ) {/** 返回重构好 this 的函数, 那么这里的 thisObject 是指向了最终 this 要指向的地方*/proxy = function() {return fn.apply( thisObject || this, arguments );};}// Set the guid of unique handler to the same of original handler, so it can be removedif ( fn ) {proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;}// So proxy can be declared as an argumentreturn proxy;}

值得关注的就是 这个 thisObject 因为 js 中 函数、对象、数组是传址的,所以 thisObject 能指向你要代理到那个对象的 this 中。感觉非常绕,但是搞明白也就没啥了。随便说下 thisObject 肯定是一个闭包了

var obj = {name: 'tudousi',test: function() {alert( this.name );return false;}};var func = $.proxy(obj, 'test');$('.show').click(func);



转载于:https://my.oschina.net/itudou/blog/346113


http://www.ppmy.cn/news/917802.html

相关文章

jQuery剥皮二 - extend

为什么80%的码农都做不了架构师?>>> jquery1.4 jquery1.4下载 这里使用了 jQuery1.4,为什么使用 1.4 因为 1.4 很多特性没有添加分析起来相对容易。 extend 可以说是 jQuery 用的最多的函数之一了,除了核心的几个函数之外其他的…

无法访问srv解析_windows能连网络,可是打不开网页,出现无法解析server的DNS

首先,我想先说作为一名刚学完计算机网络课的学生,并且还完毕了学校的号称和斯坦福一个难度级别的网络实验之后。我觉得自己对于计算机网络还是勉强入门了。对于各种之前仅仅是听过的各种tcp、http、路由器、交换机、局域网、广域网等等都有了清晰的了解了…

Git 命令初识

取自:http://www.cnblogs.com/wupeiqi/p/7295372.html Git 是一个开源的分布式版本控制软件,用以有效、高速的处理从很小到非常大的项目版本管理。 Git 最初是由Linus Torvalds设计开发的,用于管理Linux内核开发。Git 是根据GNU通用公共许可证版本2的条款…

php生成目录树

为什么80%的码农都做不了架构师&#xff1f;>>> <?php $dir E:\AppServ\www\alpaca\app;function recurDir($pathName) {$result array();$tmp array();if( !is_dir($pathName) || !is_readable($pathName) ){return null;}$allFiles scandir($pathName);f…

React Render Props 模式

为什么80%的码农都做不了架构师&#xff1f;>>> 概述 Render Props模式是一种非常灵活复用性非常高的模式&#xff0c;它可以把特定行为或功能封装成一个组件&#xff0c;提供给其他组件使用让其他组件拥有这样的能力&#xff0c;接下来我们一步一步来看React组件中…

spring boot整合scala和spark做大数据预言

原来用jetty 和 restful 做过驱动spark的计算框架&#xff0c;最近想用spring boot scala spark 重新做一个&#xff0c;一下是pom.xml 和代码分享 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.o…

matlab学习笔记三(11.2)

1.clear 的功能:清除工作间的变量。 通常的形式: 1.lear :清除工作间的所有的变量。 2.clear var:清除名为var的变量。可以 clear var*来清除所有以var开头的变量名。 >> my_func=@sinmy_func = @sin>> my_m=magic(3)my_m =8 1 63 5 74 …

golang实现ftp实时传输文件

一、项目简介 本项目主要实现的功能是ftp客户端不断地将xml文件和jpg文件实时地上传到服务器&#xff0c;当然也可以是其他格式的文件。每当ftp客户端取到一个文件之后&#xff0c;将文件上传到服务器后&#xff0c;然后将其删除。项目实现可配置&#xff0c;如果开发者有类似…