>[success] ##### 有意思的立即执行函数 ~~~ 1.问题为啥add用了闭包?https://developer.mozilla.org/zh-CN/docs/Glossary/%E7%AB%8B%E5%8D%B3%E6%89%A7%E8%A1%8C%E5%87%BD%E6%95%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F 2.第一部分是包围在 圆括号运算符 () 里的一个匿名函数,这个匿名函数拥有独立的词法作用域。 这不仅避免了外界访问此 IIFE 中的变量,而且又不会污染全局作用域。 3.在只有 var,没有 let 的旧 JavaScript 时代,诞生了一个技巧,叫做:立即执行的函数表达式(IIFE),通过创建一 个函数,并且立即执行,来构造一个新的域,从而控制 var 的范围。 ~~~ >[danger] ##### IIFE立即执行函数讲解 ~~~ 1.现在让你只用'es5'的方式'给文档添加了 20 个 div 元素,并且绑定了点击事件,打印它们的序号' ~~~ * 第一反应 ~~~ 1.但是执行后的结果是 打印二十个20,这是因为'var 只是当前作用域声明这个变量',但要注意的是 'var 除了脚本和函数体都会穿透',简单的理解就是你不是函数不是脚本我var 就和大家共享,因此最后 的结果就是大家都是'20' 因为你的'for 不是函数我就能穿透你跟大家共享' ~~~ ~~~ for(var i = 0; i < 20; i ++) { var div = document.createElement("div"); div.innerHTML = i; div.onclick = function(){ console.log(i); } document.body.appendChild(div); } ~~~ * 改正 ~~~ 1.现在知道了问题就是for不是函数导致'var穿透形成个共享',那么解决方法就是利用函数让你出不去, 老老实实一个是一个,这就是立即执行函数上场了 2.下面代码我执行完就一个新函数,我新函数里面的i 就是实际现在的,你跑不出去 ~~~ ~~~ for(var i = 0; i < 20; i ++) { void function(i){ var div = document.createElement("div"); div.innerHTML = i; div.onclick = function(){ console.log(i); } document.body.appendChild(div); }(i); } ~~~ >[danger] ##### 策略模式 ~~~ <html> <head> <meta charset="utf-8"> </head> <body> <form action="" id="registerForm" method="post"> 请输入用户名:<input type="text" name="userName"/> 请输入密码:<input type="text" name="passWord"/> 请输入手机号码:<input type="text" name="phoneNumber"/> <input type="submit" value="提交"/> </form> <script> /***************策略对象*************/ var strategies = { isNotEmpty:function(value,errorMsg){ if(value === ''){ return errorMsg; } }, minLength:function(value,length,errorMsg){ if(value.length<length){ return errorMsg; } }, isMobile:function(){ if(!/(^1[3|5|8][0-9]{9}$)/.test(value)){ return errorMsg; } } } /***************validator类***************/ var Validator = function(){ this.cache = []; }; Validator.prototype.add = function(dom,rules){ var self = this; for(var i=0,rule;rule = rules[i++];){ (function(rule){ var strategyAry = rule.strategy.split(':'); var errorMsg = rule.errorMsg; self.cache.push(function(){ var strategy = strategyAry.shift(); strategyAry.unshift(dom.value); strategyAry.push(errorMsg); return strategies[strategy].apply(dom,strategyAry); }) })(rule); } } Validator.prototype.start = function(){ for(var i=0,validatorFunc;validatorFunc = this.cache[i++];){ var errorMsg = validatorFunc(); if(errorMsg){ return errorMsg; } } } /************客户调用代码***********/ var registerForm = document.getElementById('registerForm'); var validatorFunc = function(){ var validator = new Validator(); validator.add(registerForm.userName,[{ strategy:'isNotEmpty', errorMsg:'用户名不能为空' },{strategy:'minLength:10', errorMsg:'用户名长度不能小于10位' }]); validator.add(registerForm.passWord,[{ strategy:'minLength:6', errorMsg:'用户密码不能小于6位' }]); validator.add(registerForm.phoneNumber,[{ strategy:'isMobile', errorMsg:'手机号码格式不正确' }]); var errorMsg = validator.start(); return errorMsg; } registerForm.onsubmit = function(){ var errorMsg = validatorFunc(); if(errorMsg){ alert(errorMsg); return false; } } </script> </body> </html> ~~~