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