闭包的作用域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var later;function outerFunction ( ) { var innerValue = true ; function innerFunction (paramValue ) { console .log(innerValue); console .log(paramValue); console .log(tooLate); } later = innerFunction; } outerFunction(); var tooLate = true ; later(true );
绑定函数上下文 1 2 3 4 5 6 7 8 9 10 11 var button = { clicked: false , click: function ( ) { this .clicked = true ; console .log(this ); console .log(button.clicked); } }; var elem = document .getElementById('test' );elem.addEventListener('click' , button.click, false );
在本例中,浏览器的事件处理系统认为函数调用的上下文(this)是事件的目标元素 ,所以才导致其上下文是<button>元素
,而不是button对象
1 2 3 4 5 6 7 elem.addEventListener('click' , function ( ) { button.click(); }, false ); elem.addEventListener('click' ,button.click.bind(button),false );
setTimeout和setInterval也是同样的解决方法,区别是这两个绑定的上下文(this)是window对象
更多请参考:Function.prototype.bind() - JavaScript | MDN
偏应用函数 函数科里化 1 2 3 4 5 6 7 8 9 10 11 12 13 Function .prototype.curry = function ( ) { var fn = this , args = Array .prototype.slice.call(arguments ); return function ( ) { var allArgs = Array .prototype.slice.call(arguments ).concat(args); return fn.apply(this , allArgs); } } function add (n1, n2 ) { return n1 + n2; } console .log(add.curry(1 )(4 ));
“分部”函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Function .prototype.partial = function ( ) { var fn = this , args = Array .prototype.slice.call(arguments ); return function ( ) { var j = 0 ; for (var i = 0 ; i < args.length && j < arguments .length; i++) { if (args[i] === undefined ) { args[i] = arguments [j++]; } } return fn.apply(this , args); }; }; var delay = setTimeout.partial(undefined , 1000 );delay(function ( ) { console .log('delay 1 s' ); });
使用闭包实现缓存记忆功能 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 Function .prototype.memoized = function (key ) { this ._values = this ._values || {}; console .log(this ); return this ._values[key] ? this ._values[key] : this ._values[key] = this .apply(this , arguments ); } Function .prototype.memoize = function ( ) { var fn = this ; return function ( ) { return fn.memoized.apply(fn, arguments ); } } function isPrime (num ) { var prime = num != 1 ; for (var i = 2 ; i < num; i++) { if (num % i == 0 ) { prime = false ; break ; } } return prime; } var isPrimeMemo = isPrime.memoize();console .log(isPrimeMemo(4 )); console .log(isPrimeMemo(7 )); console .log(isPrime._values);
即时函数
(…)()中,第一组圆括号仅仅是用于划定表达式的范围,而第二个圆括号则是一个操作符。eg,将函数引用通过圆括号括起来是合法的:
1 2 var someFunction = function ( ) {... };result = (someFunction)();
通过参数限制作用域内的名称 1 2 3 4 5 6 7 8 9 <img src ="../images/ninja-with-pole.png" > <script type ="text/javascript" > $ = function () {alert('not jQuery!' );}; (function ($) { $('img' ).on('click' , function (event ) { $(event.target).addClass('clickedOn' ); }); })(jQuery); </script >