思考是从jQuery的一段代码开始的。
jQuery.each({
slideDown: genFx("show", 1),
slideUp: genFx("hide", 1),
slideToggle: genFx("toggle", 1),
fadeIn: { opacity: "show" },
fadeOut: { opacity: "hide" }
}, function( name, props ) {
jQuery.fn[ name ] = function( speed, callback ) {
return this.animate( props, speed, callback );
};
});
ps:以前明哥问我想要研究js的那些部分,我当时很自然地说了fx.................
回到正题,我选的代码是1.4.1,其实在JQuery的源码中你会发现很多这样的模式
//1.4.1的版本里面大概是23处地方这样的模式
//当然里面的第一个参数可以是[],{}
//下面我就简单地以["bind","one"]举例
jQuery.each(["bind","one"],function(i,name){
//我这就简单地以jQuery.fn举例
jQuery.fn[name] = function(){
.....................
}
})
好吧 为了让大家明白,我们先来思考一下这种each的实现。
第一看看jQuery的each实现。
----ps : 这个each不是$().each
/*
一些chm或者在线的手册上会告诉你$.each有两个参数
@param {Object} object ----需要遍历的对象或者数组
@param {Function} callback(可选) ---每一个成员执行的回调
但是你看源码的时候你会发现原来有3个参数
*/
each: function( object, callback, args ) {
var name, i = 0,
//object的length
length = object.length,
//jQuery.isFunction(object) 判断是否是function
isObj = length === undefined || jQuery.isFunction(object);
if ( args ) {
if ( isObj ) {
for ( name in object ) {
if ( callback.apply( object[ name ], args ) === false ) {
break;
}
}
} else {
for ( ; i < length; ) {
if ( callback.apply( object[ i++ ], args ) === false ) {
break;
}
}
}
// A special, fast, case for the most common use of each
} else {
//一般我们多走这个,因为没有定义args--undefined
if ( isObj ) {
//for object
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
} else {
//for array
for ( var value = object[0];
i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
}
}
//返回object
return object;
},
下面先举一个简单的object参数为array的例子
/*
我这边定义的object为array
@i是index
@n是对应objetc[i]
*/
$.each( ["a","b","c"], function(i, n){
( "Item #" + i + ": " + n );
});
//这个jQuery的$.each在处理object为array的时候的源码
//其实就是开始的时候value是object[0] //this的指向!!
//如果回调函数返回的不是false的话 value每一次变成 object[++i]
//call的时候参数第一个是object[i]对象;第二个是index--i ;第三个是object[i]
for ( var value = object[0];
i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
再看看处理object为{}的例子
/*
我这边定义的是object为真正的object {}
回调的参数@param i 是key
@param n是value
*/
$.each( { name: "zhangyaochun", age: "24" }, function(i, n){
alert( "Pro: " + i + ", Value: " + n );
});
//我们来看一下jQuery的$.each处理object为{}的时候
for ( name in object ) {
//进行for in的循环
//call的第一个参数是object[name] //这个this指向!!
//call的第二个参数是name //属性
//call的第三个参数是object[name] //值
//同样如果回调返回的是false就Break
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
其实这个问题在我研究tangram和自己编写自己的凤凰lib的时候就开始think....
/*
*each-traverse a object and follow the iterator to return a obj*
*@function*
*@param {Object} source*
*@param {Function} iterator ---function(item,key)*
*@return {Object}*
*/
ZYC.object.each = function(source,iterator){
var returnValue,key,item;
if(typeof iterator == 'function'){
for(key in source){
//加了一层hasOwnProperty
if(source.hasOwnProperty(key)){
item = source[key];
//call的时候this指向的是source
//然后后面的参数依次是value和key
returnValue = iterator.call(source,item,key);
}
//如果有返回值是false的话就break
if(returnValue === false){
break;
}
}
}
return source;
};
最后还是讲一下自己的收获:思考的是一些api实现和动态扩展创建命名空间下的fn的方式,从而结合去编写改善自己的api实现方式
我在扩展我的fn的时候也参照了这样$.each的模式,动态的去扩展一下phoenix.fn[key]
5940

被折叠的 条评论
为什么被折叠?



