3 回答
TA贡献1866条经验 获得超5个赞
使用命名函数表达式:
您可以为函数表达式指定一个实际上是私有的名称,并且只有在函数内部才能看到:
var factorial = function myself (n) {
if (n <= 1) {
return 1;
}
return n * myself(n-1);
}
typeof myself === 'undefined'
下面myself是该函数的可见里面只有自己。
您可以使用此私有名称来递归调用该函数。
请参阅13. Function DefinitionECMAScript 5规范:
可以从FunctionExpression的FunctionBody内部引用FunctionExpression中的标识符,以允许该函数以递归方式调用自身。但是,与FunctionDeclaration中的功能不同,FunctionExpression中的Identifier不能从中引用,也不会影响包围FunctionExpression的作用域。
请注意,版本8之前的Internet Explorer的行为不正确,因为该名称实际上在封闭的变量环境中可见,并且它引用了实际功能的副本(请参见下面的patrick dw的注释)。
使用arguments.callee:
或者,您可以arguments.callee用来引用当前函数:
var factorial = function (n) {
if (n <= 1) {
return 1;
}
return n * arguments.callee(n-1);
}
ECMAScript的第五版禁止在严格模式下使用arguments.callee(),但是:
(来自MDN):在常规代码中arguments.callee指的是封闭函数。这个用例很弱:只需命名封闭函数即可!而且,arguments.callee实质上阻碍了诸如内联函数之类的优化,因为如果访问arguments.callee,则必须使其能够提供对未内联函数的引用。严格模式功能的arguments.callee是不可删除的属性,在设置或检索时会抛出该属性。
TA贡献1806条经验 获得超5个赞
您可以使用arguments.callee [MDN]来访问函数本身:
if (counter>0) {
arguments.callee(counter-1);
}
但是,这将在严格模式下中断。
TA贡献1906条经验 获得超10个赞
您可以使用Y-combinator:(Wikipedia)
// ES5 syntax
var Y = function Y(a) {
return (function (a) {
return a(a);
})(function (b) {
return a(function (a) {
return b(b)(a);
});
});
};
// ES6 syntax
const Y = a=>(a=>a(a))(b=>a(a=>b(b)(a)));
// If the function accepts more than one parameter:
const Y = a=>(a=>a(a))(b=>a((...a)=>b(b)(...a)));
您可以这样使用它:
// ES5
var fn = Y(function(fn) {
return function(counter) {
console.log(counter);
if (counter > 0) {
fn(counter - 1);
}
}
});
// ES6
const fn = Y(fn => counter => {
console.log(counter);
if (counter > 0) {
fn(counter - 1);
}
});
添加回答
举报