您的位置:首页 > Web前端 > JavaScript

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;

这项技术对于某些浏览器相关的操作会很有用,那把她们放到之后再讲吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: