源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
查看: 20|回复: 20

[JavaScript] JQuery 动态扩展对象之另类视角

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2010-5-25 23:33:02 | 显示全部楼层 |阅读模式
大家都知道javascript是动态语言,它对动态的支持是与身俱来的。 例如:有一个employee对象,
复制代码 代码如下:
function employee(){
this.e_id = 0;
this.e_name = "";
}

  现在需要为它动态的新增"age"属性和"toString()"方法,
复制代码 代码如下:
var empObj = new employee();
empObj["age"] = 20;
empObj["toString"] = function() { return this.e_id.toString() + this.e_name; };

  一行简单的代码就承担了这项工作,这是Javascript内置支持的,不过往往我们需要在这基础上支持一定程度的扩展,所以会将这一行简单的代码抽成一个方法:
复制代码 代码如下:
function dym_setprop(obj, key, value) {
if (obj && key) {
obj[key] = value;
}
}

  看到这里,我们先让思路做个跳转,跳到C#中的employee对象,如下:

在面向对象的编程中,对外使用的都是属性(Get/Set),那么想想如何将这种方式签入到Javascript中,现在让我们跳回dym_setprop函数内,既在dym_setprop方法中不能使用obj[key]=value的直接赋值方式,而要支持Set。
复制代码 代码如下:
function dym_setprop(obj, key, value, fn) {
if (obj && key) {
fn(obj, key, value);
}
}

  参数fn,在dym_setprop中不直接操作任何对象,使用函数fn来代替相应的操作代码,则在这里除了支持Set外,还有其他很大的自由空间。
让我们继续深入dym_setprop方法,现在我们把关注点放在参数value上,大家都清楚value可以是值类型,也可以是函数,对于值类型来说,不用考虑其他东西直接赋值就可以了,对于函数来说就没有这么简单,它支持两种操作:

1、直接将函数赋给新扩展的属性

2、将函数执行的返回值赋给新扩展的属性
复制代码 代码如下:
function dym_setprop(obj, key, value, fn, exec, pass) {
if (obj && key) {
var temp = value;
if (exec) {
temp = value.call(obj, key, fn(obj, key));
}
fn(obj, key, temp, pass);
}
}

在这段代码中参数exec充当了上面两种操作选择的角色,参数pass是一个额外的执行参数。除此之外,大家也许会对fn有些疑惑,因为上面有两个地方使用了,区别只有参数个数不同,fn到底代表什么?!再次想下C#中的属性,它是有Get/Set的,那么在这里fn(obj,key)就相当与Get,而fn(obj,key,temp,pass)就相当与Set。

  例如:看下面的代码,对于fn的定义与使用,
复制代码 代码如下:
employee.AccessProp = function(obj, key, value) {
if (value) {
obj[key] = value;
}
else {
return obj[key];
}
}

dym_setprop(empObj, "age", function(key, value) { return value + 10; }, employee.AccessProp, true);

看了这么多,也许大家觉得郁闷,简单的动态扩展对象程序为什么要以这种方式来编写,有种没事找事的感觉,其实不然,如果你只想做动态扩展对象,那么我建议你别采用上述dym_setprop的思路,但是如果你想从更加抽象的角度上思考,将dym_setprop内的程序作为一个流程执行的模板,那么这是一个不错的方式,因为dym_setprop内部不承担任何具体代码(obj[key]=value或obj[key])的执行,它都通过函数fn来代替,这样对于具体执行来说有完全自由的空间。

  理解完上述的思路后,让我们进入本文的核心,JQuery是如何实现动态扩展对象的?access函数,
复制代码 代码如下:
function access( elems, key, value, exec, fn, pass ) {
var length = elems.length;

// Setting many attributes
if ( typeof key === "object" ) {
for ( var k in key ) {
access( elems, k, key[k], exec, fn, value );
}
return elems;
}
// Setting one attribute
if ( value !== undefined ) {
// Optionally, function values get executed if exec is true
exec = !pass && exec && jQuery.isFunction(value);

for ( var i = 0; i < length; i++ ) {
fn( elems, key, exec ? value.call( elems, i, fn( elems, key ) ) : value, pass );
}
return elems;
}
// Getting an attribute
return length ? fn( elems[0], key ) : null;
}


仔细看完access函数的代码,你一定发现它和dym_setprop的相试度很高,它只是多了一段代码:
复制代码 代码如下:
if ( typeof key === "object" ) {
for ( var k in key ) {
access( elems, k, key[k], exec, fn, value );
}
return elems;
}
很容易看出它其实就是用来支持object对象的动态扩展属性。具体的执行流程通过下图来展示:

到这里已经写完了,本文试着从自己的角度上去猜测JQuery的开发者是如何设计出access函数的,让它去支持动态扩展对象,并且说明了access的执行流程。其实对于我的这种猜测不一定正确,不过不妨碍我对于JQuery的研究。
回复

使用道具 举报

11

主题

2万

回帖

300

积分

中级会员

Rank: 3Rank: 3

积分
300
发表于 2022-11-5 14:24:32 | 显示全部楼层
笑纳了老板
回复 支持 反对

使用道具 举报

5

主题

2万

回帖

183

积分

注册会员

Rank: 2

积分
183
发表于 2022-11-20 20:22:51 | 显示全部楼层
给爸爸爸爸爸爸爸爸爸爸八佰伴八佰伴
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

319

积分

中级会员

Rank: 3Rank: 3

积分
319
发表于 2023-4-13 19:17:58 | 显示全部楼层
怕怕怕怕怕怕怕怕怕怕怕怕怕怕
回复 支持 反对

使用道具 举报

15

主题

2万

回帖

122

积分

注册会员

Rank: 2

积分
122
发表于 2023-9-18 15:58:11 | 显示全部楼层
不错的源码论坛
回复 支持 反对

使用道具 举报

4

主题

2万

回帖

303

积分

中级会员

Rank: 3Rank: 3

积分
303
发表于 2023-10-24 08:48:27 | 显示全部楼层
呵呵呵呵呵呵呵a
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

186

积分

注册会员

Rank: 2

积分
186
发表于 2024-3-29 20:05:23 | 显示全部楼层
建军节建军节建军节建军节
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

68

积分

注册会员

Rank: 2

积分
68
发表于 2024-7-9 19:34:23 | 显示全部楼层
啦啦啦啦啦啦啦啦!
回复 支持 反对

使用道具 举报

6

主题

1万

回帖

174

积分

注册会员

Rank: 2

积分
174
发表于 2024-8-8 08:43:21 | 显示全部楼层
还有人在不。。。。。。。。。。啊
回复 支持 反对

使用道具 举报

4

主题

2万

回帖

316

积分

中级会员

Rank: 3Rank: 3

积分
316
发表于 2024-9-10 20:01:19 | 显示全部楼层
啊,数码撒飒飒飒飒
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2025-1-20 21:02 , Processed in 0.098757 second(s), 26 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表