JavaScript 匿名函数

示例

定义一个匿名函数

定义函数后,通常会给它一个名称,然后使用该名称调用它,如下所示:

foo();

function foo(){

    // ...

}

当您以这种方式定义函数时,Javascript运行时会将函数存储在内存中,然后使用您为其分配的名称创建对该函数的引用。然后可以在当前范围内访问该名称。这是创建函数的一种非常方便的方法,但是Javascript不需要您为函数分配名称。以下内容也完全合法:

function() {

    // ...

}

当定义一个没有名称的函数时,它称为匿名函数。该函数存储在内存中,但是运行时不会自动为您创建对该函数的引用。乍一看,似乎没有任何用处,但在许多情况下匿名功能非常方便。

将匿名函数分配给变量

匿名函数的一种非常常见的用法是将它们分配给变量:

var foo = function(){ /*...*/ };

foo();

在函数作为变量中将更详细地介绍匿名函数的使用。

将匿名函数作为参数提供给另一个函数

某些函数可以接受对函数的引用作为参数。这些有时称为“依赖注入”或“回调”,因为它允许您的调用函数“回调”您的代码,从而使您有机会更改被调用函数的行为方式。例如,使用Array对象的map函数,您可以遍历数组的每个元素,然后通过对每个元素应用转换函数来构建新的数组。

var nums = [0,1,2];

var doubledNums = nums.map( function(element){ return element * 2; } ); // [0,2,4]

创建一个命名函数将是乏味,草率且不必要的,这将使您的作用域仅在此位置需要一个函数而变得混乱,并破坏了代码的自然流动和可读性(同事必须离开此代码才能找到您的代码)功能以了解发生了什么)。

从另一个函数返回一个匿名函数

有时,将一个函数作为另一个函数的结果返回是很有用的。例如:

var hash = getHashFunction( 'sha1' );

var hashValue = hash( 'Secret Value' );

function getHashFunction( algorithm ){

    if ( algorithm === 'sha1' ) return function( value ){ /*...*/ };

    else if ( algorithm === 'md5' ) return function( value ){ /*...*/ };

}

立即调用匿名函数

与许多其他语言不同,Javascript的作用域是函数级的,而不是块级的。(请参阅功能范围)。但是,在某些情况下,有必要创建一个新的作用域。例如,通过<script>标签添加代码时通常会创建一个新的作用域,而不是允许在全局作用域中定义变量名(这会冒其他脚本与您的变量名冲突的风险)。处理这种情况的常用方法是定义一个新的匿名函数,然后立即调用它,将变量安全地隐藏在匿名函数的范围内,而无需通过泄漏的函数名使第三方可以访问您的代码。例如:

<!-- My Script -->

<script>

function initialize(){

    // foo安全地隐藏在initialize中,但是...

    var foo = '';

}

// ...my initialize function is now accessible from global scope.

// 有人可能会再次调用它(可能是无意中)。

initialize();

</script>

<script>

// 使用匿名函数,然后立即

// 调用它,隐藏我的foo变量并保证

// 没有人可以第二次称呼它。

(function(){

    var foo = '';

}()) // <--- the parentheses invokes the function immediately

</script>

自引用匿名函数

有时,匿名函数能够引用自身很有用。例如,该函数可能需要递归调用自身或为其添加属性。但是,如果函数是匿名的,则可能会非常困难,因为它需要知道已将函数分配给该变量的知识。这是不太理想的解决方案:

var foo = function(callAgain){

    console.log( 'Whassup?' );

    // 不太理想...我们依赖可变参考...

    if (callAgain === true) foo(false);

};

foo(true);

// 控制台输出:

// 没话说

// 没话说

// 将bar分配给原始函数,并将foo分配给另一个函数。

var bar = foo;

foo = function(){

    console.log('Bad.')

};

bar(true);

// 控制台输出:

// 没话说

// 坏。

此处的目的是让匿名函数递归调用自身,但是当foo的值更改时,最终会导致潜在的难以跟踪的错误。

相反,我们可以通过给匿名函数一个私有名称来为其提供对自身的引用,如下所示:

var foo = function myself(callAgain){

    console.log( 'Whassup?' );

    // 不太理想...我们依赖可变参考...

    if (callAgain === true) myself(false);

};

foo(true);

// 控制台输出:

// 没话说

// 没话说

// 将bar分配给原始函数,并将foo分配给另一个函数。

var bar = foo;

foo = function(){

    console.log('Bad.')

};

bar(true);

// 控制台输出:

// 没话说

// 没话说

请注意,函数名称仅限于自身。该名称尚未泄漏到外部作用域中:

myself(false); // ReferenceError:我自己未定义

当将递归匿名函数作为回调参数处理时,此技术特别有用:

5
// 计算数组中每个数字的斐波那契值:

var fib = false,

    result = [1,2,3,4,5,6,7,8].map(

        function fib(n){

            return ( n <= 2 ) ? 1 : fib( n - 1 ) + fib( n - 2 );

        });

// 结果= [1、2、3、5、8、13、21]

// fib = false(匿名函数名称未覆盖我们的fib变量)

以上是 JavaScript 匿名函数 的全部内容, 来源链接: utcz.com/z/350097.html

回到顶部