闭包的应用场景
setTimeout,click
timer
http://blog.csdn.net/yanghua_kobe/article/details/6780181
场景一:采用函数引用方式的setTimeout调用(和click一样)
闭包的一个通常的用法是为一个在某一函数执行前先执行的函数提供参数。例如,在web环境中,一个函数作为setTimeout函数调用的第一个参数,是一种很常见的应用。
setTimeout将要执行的函数(或者一段javascript代码,但这不是我们要讨论的情况)作为它的第一个参数,下一个参数是需要延迟执行的时间。如果一段代码想通过setTimeout来调用,那么它需要传递一个函数对象的引用来作为第一个参数。延迟的毫秒数作为第二个参数,但这个函数对象的引用无法为将要被延迟执行的对象提供参数。
但是,可以调用另一个函数来返回一个内部函数的调用,将那个内部函数对象的引用传递给setTimeout函数。内部函数执行时需要的参数,在调用外部函数时传递给它。setTimeout在执行内部函数时无需传递参数,因为内部函数仍然能够访问外部函数调用时提供的参数
var p1 = "ss"; var p2 = "jj"; function testSetTime(para1,para2){ return (function(){ console.log(para1 + "-" + para2); }) } var test = testSetTime(p1, p2); setTimeout(test, 1000); setTimeout(function(){ console.log(p1 + "-" + p2) },1000)
场景二:Singleton 单件(每个js都这么用的,其实就是代码模块化)
http://coolshell.cn/articles/6731.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var singleton = function () { var privateVariable; function privateFunction(x) { ...privateVariable... } return { firstMethod: function (a, b) { ...privateVariable... }, secondMethod: function (c) { ...privateFunction()... } }; }(); |
这个单件通过闭包来实现。通过闭包完成了私有的成员和方法的封装。匿名主函数返回一个对象。对象包含了两个方法,方法1可以方法私有变量,方法2访问内部私有函数。需要注意的地方是匿名主函数结束的地方的'()’,如果没有这个'()’就不能产生单件。因为匿名函数只能返回了唯一的对象,而且不能被其他地方调用。这个就是利用闭包产生单件的方法。
base,salesModel每个页面都只有一个,都是单件。
http://yuiblog.com/blog/2006/11/27/video-crockford-advjs/
http://codethoughts.info/javascript/2015/05/22/javascript-closure-inside-out/
场景三:单例模式(本质上一样,只是不同用途)
但凡写过代码的人应该对单例模式都不陌生,这里我也就不在多阐述了,直接上代码:
var Singleton = (function () { var instance; function createInstance() { return new Object("I am the instance"); } return { getInstance: function () { if (!instance) { instance = createInstance(); } return instance; } }; })(); function run() { var instance1 = Singleton.getInstance(); var instance2 = Singleton.getInstance(); console.log("Same instance? " + (instance1 === instance2)); }
我们是这么用的,jQuery就是
//单例模式 (function(){ var instanced; var index = function(){ this.name = "sss"; } index.prototype = { init: function(){ console.log("start") }, instance: function(){ if(!instanced){ instanced = new index(); } return instanced; } } new index().instance().init(); })()
场景四:要clear自身timer
$(".outer").each(function () { var el = this var s = Number($(el).attr("data-seconds")) || 0 //attr得到的是字符串,先转换成数字,避免NaN。给默认为0 var id = setInterval(function () {//闭包 $(el).html(s--) if (s === 0) { $(el).html("倒时计结束!") clearInterval(id) } }, 1000) })
使用闭包的正确姿势:保留一下公用变量
function show(data, ele) { (ele || $("body")).append('<li>' + data + '</li>') } function task1(name, fn){ setTimeout(function(){ fn(name) }, 500) } function task2(name, fn){ setTimeout(function(){ fn(name) }, 1000) } var taskNuns = function(){ var num = 2; return function() {//使用闭包保留了num; if (num === 1) { show("任务都完成了", $("#aaron1")) } num--; } }() $("#aaron1").click(function(){ // task1('任务一', function(name){ //点击并且500ms后 console.log(name); show("task1", $("#aaron1")); taskNuns(); }) task2('任务二', function(name){ //点击并且500ms后 console.log(name); show("task2", $("#aaron1")); taskNuns(); }) })
http://www.imooc.com/code/3747