[转帖]Mootools源码分析-08 -- Function
原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-401135
原作者:我佛山人
/*
对Function对象的扩展,最令人激动的部分,JS框架必不可少的部分
由于JS中只有函数是安全的作用域(with不可靠),所以优雅的JS OOP有赖于此
只是有一点,不知道moo为什么不实现函数的柯里化,而Prototype中有相应实现
*/
Function.implement({
//扩展方法,moo中很多对象都
有同名方法的实现
extend: function(properties) {
for (var property in properties) this[property] = properties[property];
return this;
},
//创建新函数,功能最强的实现,后面的其它扩展都依赖于它的实现
create: function(options) {
//将上下文对象指向一个临时变量,以便在闭包中使用
var self = this;
//又见||的写法
options = options || {};
//返回一个闭包,其中event参数主要用于非IE浏览器中事件对象的引用
return function(event) {
//同样,用于闭包使用的变量
var args = options.arguments;
args = $defined(args) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0);
/*
是否需要捕获事件
对象,可以看到仍然将事件对象作为第一个参数
因此在使用bindWithEvent时,需要记你的方法/函数的第一个参数是事件
*/
if (options.event) args = [event || window.event].extend(args);
//闭包中的闭包
var returns = function() {
return self.apply(options.bind || null, args);
};
//指定延迟执行函数
if (options.delay) return setTimeout(returns, options.delay);
//指定周期性执行函数
if (options.periodical) return setInterval(returns, options.periodical);
//指定尝试执行函数,用$try忽略错误
if (options.attempt) return $try(returns);
return returns();
};
},
//制造一个已提供所需要参数的函数,之后再执行时就不必再传参数
pass: function(args, bind) {
return this.create({arguments: args, bind: bind});
},
//尝试执行函数而忽略错误信息
attempt: function(args, bind) {
return this.create({arguments: args, bind: bind, attempt: true})();
},
//在旧函数基础上绑定指向函数内this的新函数
bind: function(bind, args) {
return this.create({bind: bind, arguments: args});
},
//创建一个绑定事件对象的函数
bindWithEvent: function(bind, args) {
return this.create({bind: bind, event: true, arguments: args});
},
//延时执行函数,注意参数的顺序和对应的意义
delay: function(delay, bind, args) {
return this.create({delay: delay, bind: bind, arguments: args})();
},
//周期性执行函数,注意参数的顺序和对应的意义
periodical: function(interval, bind, args) {
return this.create({periodical: interval, bind: bind, arguments: args})();
},
//柯里化,我自己所加,非moo内置
curry: function() {
if (!arguments.length) return this;
var self = this, args = $A(arguments);
return function() {
return self.apply(this, args.extend($A(arguments)));
}
},
//直接执行函数,和直接加()执行相比,可提供改变this的对象
run: function(args, bind) {
return this.apply(bind, $splat(args));
}
});
对Function对象的扩展,最令人激动的部分,JS框架必不可少的部分
由于JS中只有函数是安全的作用域(with不可靠),所以优雅的JS OOP有赖于此
只是有一点,不知道moo为什么不实现函数的柯里化,而Prototype中有相应实现
*/
Function.implement({
//扩展方法,moo中很多对象都
有同名方法的实现
extend: function(properties) {
for (var property in properties) this[property] = properties[property];
return this;
},
//创建新函数,功能最强的实现,后面的其它扩展都依赖于它的实现
create: function(options) {
//将上下文对象指向一个临时变量,以便在闭包中使用
var self = this;
//又见||的写法
options = options || {};
//返回一个闭包,其中event参数主要用于非IE浏览器中事件对象的引用
return function(event) {
//同样,用于闭包使用的变量
var args = options.arguments;
args = $defined(args) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0);
/*
是否需要捕获事件
对象,可以看到仍然将事件对象作为第一个参数
因此在使用bindWithEvent时,需要记你的方法/函数的第一个参数是事件
*/
if (options.event) args = [event || window.event].extend(args);
//闭包中的闭包
var returns = function() {
return self.apply(options.bind || null, args);
};
//指定延迟执行函数
if (options.delay) return setTimeout(returns, options.delay);
//指定周期性执行函数
if (options.periodical) return setInterval(returns, options.periodical);
//指定尝试执行函数,用$try忽略错误
if (options.attempt) return $try(returns);
return returns();
};
},
//制造一个已提供所需要参数的函数,之后再执行时就不必再传参数
pass: function(args, bind) {
return this.create({arguments: args, bind: bind});
},
//尝试执行函数而忽略错误信息
attempt: function(args, bind) {
return this.create({arguments: args, bind: bind, attempt: true})();
},
//在旧函数基础上绑定指向函数内this的新函数
bind: function(bind, args) {
return this.create({bind: bind, arguments: args});
},
//创建一个绑定事件对象的函数
bindWithEvent: function(bind, args) {
return this.create({bind: bind, event: true, arguments: args});
},
//延时执行函数,注意参数的顺序和对应的意义
delay: function(delay, bind, args) {
return this.create({delay: delay, bind: bind, arguments: args})();
},
//周期性执行函数,注意参数的顺序和对应的意义
periodical: function(interval, bind, args) {
return this.create({periodical: interval, bind: bind, arguments: args})();
},
//柯里化,我自己所加,非moo内置
curry: function() {
if (!arguments.length) return this;
var self = this, args = $A(arguments);
return function() {
return self.apply(this, args.extend($A(arguments)));
}
},
//直接执行函数,和直接加()执行相比,可提供改变this的对象
run: function(args, bind) {
return this.apply(bind, $splat(args));
}
});

浙公网安备 33010602011771号