javascript 函数初探 (五)--- 几种类型的函数
2016-08-27 08:58
176 查看
即时函数:
目前我们已经讨论了匿名函数在回调时的应用。接下来,我们来看看匿名函数的另一种应用实例 --- javascript即时函数:比如:
( function(){ alert('her'); } )()
虽然这种语法看上去有点吓人,但其实非常的简单 --- 我们只需将匿名函数的定义放进一对括号中,然后外面再紧跟一对括号即可。
其中第二对括号起到了 ‘立即调用’ 的作用,同时她也是我们向匿名函数传递参数的地方。
( function(a){ alert( 'her is' + a + '!' ) } )('beauty');
另外,您也可以将第一对括号闭合与第二对括号之后,这两种做法都有效:
// 第一种 (function(){ alert(); })() // 第二种 (function(){ alert() }())
使用即时函数(自调函数)的好处是不会产生任何全局变量。当然,缺点也是显而易见的,这种函数是无法重复执行的(除非您将她放入某个循环中,或其他函数中)。这个特性也使得即时函数非常适合于执行一些一次性的初始化任务。
如果有需要的话,即时函数也能带有返回值,虽然并不常见:
var her = (function(){ return 'She was really beautiful'; })();
当然在这个例子中,将整个函数表达式用括号包起来是不必要的,我们只需在函数最后使用一对括号来执行这个函数即可。因此也可以改为:
var her = function(){ return 'She was really beautiful'; }();
但这种写法可读性差了些,不读到最后我们不会知道这是个即时函数还是其他的神马。
内部(私有)函数:
相比我们都记得,之前说过:函数与其他类型的值本质上是一样的,因此,我们没有理由阻止在一个函数体内部定义另一个函数:function person(){ function her(){ return 'She was really beautiful'; } return 'Hello' }
我们当然也可以用函数标示法来写这段代码:
var person = function(){ var her = function(){ return 'She was really beautiful'; } return 'Hello' }
当我们调用全局函数person()时,本地函数her()也会在其内部被调用。由于her()是一个本地函数,所以在person()函数以外是不可见的。所以我们称her()为私有函数(内部函数)。
使用私有函数有以下几个优点:
1. 有助于我们确保全局命名空间的纯净性(这意味着命名冲突的机会很小);
2. 确保私有性 --- 这使得我们可以选择只将一些必要的函数暴露给‘外部世界’,而保留属于自己的函数,使得她们不该为程序其他部分所使用。 (¬_¬)除非你是一个暴露狂!!!
返回函数的函数:
正如之前所讲,函数始终都会有一个返回值的,即使不是显示return返回,她也会隐式的返回一个undefined。既然函数能返回一个唯一的值,那么这个值也可以会是一个函数。(这个年头也计划生育了!!)例如:
function her(){ alert('Hello'); return function(){ alert('My son!') } }
在这个例子中,函数her()会在执行她的工作(弹出‘Hello’)之后返回另一个函数。而返回的函数又会去执行另外一些事情(弹出My son)。我们只需将返回值附给某个变量,那我们就可以像使用一般函数那样调用这个变量了。
var she = her(); she(); // 'hello'
如上所见 首先会弹出alert('Hello'),然后调用返回的函数才会弹出alert('My son!');
如果您像将返回的函数立即执行,也可以不将她付给某个变量,直接在她后面加一个括号:
her()(); // 'Hello' 'My son'
能重写自己的函数:
由于一个函数可以返回另一个函数,那么,我们可以用新的函数来覆盖旧的函数。如之前的一个例子:her = her()
当然这句仍然只会执行弹出‘Hello’,如果我们再次调用her(),她就会执行alert(‘My son’)了。这对于要执行某些一次性初始化的函数非常有用。该函数会在第一次被调用的时候重写自己:
function her(){ alert('Hello'); return function(){ alert('My son!') } }
第一次被调用就会变成:
function(){ alert('My son!') }
从而避免了每次调用重复一些不必要的工作。
在上面的例子中,我们是在外面重新定义her函数的 --- 即我们将函数返回值赋给函数本身。我们也可以在函数内部重写自己。
function her(){ alert('Hello'); her = function(){ alert('My son!') } }
这样一来,我们在第一次调用该函数时会有如下情况发生:
1. alert(‘Hello’)将会被执行(可以视为一次性的准备工作);
2. 全局变量her将会被重新定义,并赋予一个新的函数;
如果该函数再次被调用的话,被执行的将会是alert(‘Hello Myson’)了。
下面我们看一个组合型的应用:
var her = (function(){ function son(){ var setup = 'done' }; function girl(){ alert('her is my mom'); }; son(); return gril; })();
在这个例子中有如下情况:
1. 我们使用了私有函数 son()和 girl();
2. 我们也使用了即时函数her;
3. 当该函数第一次被调用时,她会调用son(),并返回函数girl的一个函数引用。请注意这里是不带括号的,并不会产生函数girl的调用;
4. 由于这里执行的语句是有 var her = .... 开头的,因此该自调函数的返回值girl会重新赋值给her;
这项技术对于某些浏览器相关的操作会很有用,那把她们放到之后再讲吧。
相关文章推荐
- isArray()函数(JavaScript中对象类型判断的几种方法)
- JavaScript创建函数的几种类型
- isArray()函数(JavaScript中对象类型判断的几种方法)
- isArray()函数(JavaScript中对象类型判断的几种方法)
- isArray()函数(JavaScript中对象类型判断的几种方法)
- Javascript isArray 数组类型检测函数
- Javascript isArray 数组类型检测函数
- javascript检查数值类型函数
- Javascript 判断函数类型完美解决方案
- javascript身份证号码验证函数支持带x类型的身份证
- JavaScript判断变量类型:typeof函数与constructor属性异同
- JavaScript判断变量类型:typeof函数与constructor属性异同
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->clear 函数
- 面向对象的 Javascript 函数重载和类型检查
- javascript 简单高效判断数据类型 系列函数 By shawl.qiu
- javascript 简单高效判断数据类型系列函数 (转) By shawl.qiu
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->addRange 函数
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->add 函数
- javascript 扩充String类型的函数功能
- Javascript 判断函数类型完美解决方案