// 创建一个用于设置prototype的公共函数对象
var ctor = function() {};
1、.bind(function, object, [*arguments])
:绑定function到object,任何时候调用函数,都指向这个object。不能绑定两个对象。没看明白
其实apply和call也能改变this的指定,只是bind之后,可以省略掉apply和call
_.bind = function bind(func, context) {
var bound, args;
if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
if (!_.isFunction(func)) throw new TypeError;
args = slice.call(arguments, 2);
return bound = function() {
//什么时候this instanceof bound = true?
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
ctor.prototype = func.prototype;
var self = new ctor;
var result = func.apply(self, args.concat(slice.call(arguments)));
if (Object(result) === result) return result;
return self;
};
};
2、_.bindAll():把methodNames参数指定的方法绑定到object上,这些方法就会在对象的上下文环境中执行。绑定函数用作事件处理函数时非常便利,否则函数被调用时this一点用也没有。如果不设置methodNames参数,对象上的所有方法都会被绑定。
_.bindAll = function(obj) { var funcs = slice.call(arguments, 1); //返回对象所有的方法名 if (funcs.length == 0) funcs = _.functions(obj); each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); return obj; };
//实例:如果不bindAll,点击#bindall的话,会alert undefined
var buttonView = { label : 'underscore', onClick: function(){ alert('clicked: ' + this.label); }, onHover: function(){ console.log('hovering: ' + this.label); } }; _.bindAll(buttonView, 'onClick', 'onHover'); $('#bindall').on('click', buttonView.onClick);
3、_.memoize():将返回一个函数, 该函数集成了缓存功能,经过计算的值缓存到局部变量并在下次调用时直接返回
_.memoize = function(func, hasher) { var memo = {}; hasher || (hasher = _.identity); return function() { //arguments是memoize返回函数的参数 var key = hasher.apply(this, arguments); //如果memo有key,return memo[key];如果没有key,memo[key]为函数的返回值,并返回memo[key] return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); }; };
4、_.delay():等待wait毫秒后调用function。如果传递可选的参数arguments,当函数function执行时, arguments 会作为参数传入。
_.delay = function(func, wait) { //args是要传给func的参数,arguments从0开始 var args = slice.call(arguments, 2); return setTimeout(function(){ return func.apply(null, args); }, wait); };
5、_.defer():延迟调用function直到当前调用栈清空为止,类似使用延时为0的setTimeout方法。对于执行开销大的计算和无阻塞UI线程的HTML渲染时候非常有用。 如果传递arguments参数,当函数function执行时, arguments 会作为参数传入。
_.defer = function(func) { //[func, 1].concat(slice.call(arguments, 1))传给delay,等待1ms,参数为arguments[1] return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); };
TAT.weber浅谈javascript的函数节流:http://www.alloyteam.com/2012/11/javascript-throttle/
_.once():创建一个只会被执行一次的函数, 如果该函数被重复调用, 将返回第一次执行的结果.该函数用于获取和计算固定数据的逻辑, 如获取用户所用的浏览器类型.作为初始化函数使用时非常有用, 不用再设一个boolean值来检查是否已经初始化完成.
_.once = function(func) { var ran = false, memo; return function() { if (ran) return memo; ran = true; return memo = func.apply(this, arguments); }; };
_.wrap():返回一个函数, 该函数会将当前函数作为参数传递给一个包裹函数,在包裹函数中可以通过第一个参数调用当前函数, 并返回结果
一般用于多个流程处理函数的低耦合组合调用
_.wrap = function(func, wrapper) { return function() { //arguments是返回函数的参数 var args = [func].concat(slice.call(arguments, 0)); return wrapper.apply(this, args); }; }; // 实例 var hello = function(name) { return "hello: " + name; }; hello = _.wrap(hello, function(func) { return "before, " + func("moe") + ", after"; }); hello(); => 'before, hello: moe, after'
_.compose():返回函数集 functions 组合后的复合函数, 也就是一个函数执行完之后把返回的结果再作为参数赋给下一个函数来执行. 以此类推. 在数学里, 把函数 f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h()))
_.compose = function() { var funcs = arguments; return function() { var args = arguments; //依次执行嵌套函数 for (var i = funcs.length - 1; i >= 0; i--) { args = [funcs[i].apply(this, args)]; } return args[0]; }; };
_.after():创建一个函数, 只有在运行了 count 次之后才有效果. 在处理同组异步请求返回结果时, 如果你要确保同组里所有异步请求完成之后才 执行这个函数, 这将非常有用.
_.after = function(times, func) { if (times <= 0) return func(); return function() { if (--times < 1) { return func.apply(this, arguments); } }; };