递归|两个函数名称 [英] Recursion | Two function names

查看:88
本文介绍了递归|两个函数名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是Douglas Crockford的The Good Parts的代码。

Below is code from Douglas Crockford's The Good Parts.

在大多数情况下,代码是有意义的。除此之外,我不明白这一行:

For most part the code makes sense. Except, I don't understand this line here:

var walk_the_DOM = function walk(node, func) {

因为看起来该函数有两个名字 - walk_the_dom() walk()

as it appears the function is given two names - walk_the_dom() and walk()

进一步下来你可以看到代码实际上是双向调用的,所以确实这些名称引用了这个函数。

Further down you can see the code is actually called both ways so that indeed both of these names reference the function.

为什么这个函数有两个名字?

Why is this function given two names?

// Define a walk_the_DOM function that visits every
// node of the tree in HTML source order, starting
// from some given node. It invokes a function,
// passing it each node in turn. walk_the_DOM calls
// itself to process each of the child nodes.

var walk_the_DOM = function walk(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {

        // walk() called here

        walk(node, func);
        node = node.nextSibling;
    }
};

// Define a getElementsByAttribute function. It
// takes an attribute name string and an optional
// matching value. It calls walk_the_DOM, passing it a
// function that looks for an attribute name in the
// node. The matching nodes are accumulated in a
// results array.

var getElementsByAttribute = function (att, value) {
    var results = [];

   // walk_the_DOM() called here

    walk_the_DOM(document.body, function (node) { 
        var actual = node.nodeType === 1 && node.getAttribute(att);
        if (typeof actual === 'string' &&
                (actual === value || typeof value !== 'string')) {
            results.push(node);
        }
    });

    return results;
};


推荐答案

这是为了让递归安全地工作,我想。

This is in order for the recursion to work safely, I would imagine.

例如,如果你只想使用 walk_the_DOM 名称,可以重新分配变量之后,或由于范围而无法访问,因此在函数本身内部使用它是不安全的。

For example, if you wanted to only use the walk_the_DOM name, the variable could be reassigned later on, or not accessible due to the scope, so it is not safe to use it inside of the function itself.

我做了一些研究,这就是我发现的。首先,请参阅ECMAScript 5规范, 第13节
定义函数的方法有两种:a)使用 FunctionDeclaration ,b)使用 FunctionExpression

I've done some research, and here's what I found. First of all, refer to ECMAScript 5 specification, section 13. There are two ways to define a function: a) using FunctionDeclaration, and b) using FunctionExpression.

它们看起来非常相似,但也有所不同。以下是 FunctionDeclaration

They look very similar, but are also somewhat different. The following is a FunctionDeclaration:

function f() { };

这两个都是 FunctionExpression

var x = function() { };
var y = function f() { };

我们感兴趣的部分是 FunctionExpression 。如果 var y = function f(){} ,标识符 f 从函数体内部可见。换句话说,在 {} 之外的任何地方, typeof f 将返回 undefined

The interesting part for us is about FunctionExpression. In case of var y = function f() { }, the identifier f is only visible from inside the function body. In other words, anywhere outside of { }, typeof f will return undefined.

现在是一些实际例子的时候了。假设我们想使用 FunctionDeclaration 编写一个递归函数:

Now it's time for some practical examples. Let's say we want to write a recursive function using FunctionDeclaration:

function f1(x) { x > 5 ? console.log("finished") : f1(x + 1) };

现在我们要将函数复制到另一个变量并设置 f1 到其他地方:

Now we want to "copy" the function to another variable and to set f1 to something else:

var f2 = f1;
var f1 = function() { console.log("Kitteh") };

但这不能按预期工作:

f2(1); // outputs: Kitteh

现在,如果您使用Douglas Crockford定义递归函数的方式:

Now if you used the Douglas Crockford's way of defining a recursive function:

var f1 = function myself(x) { x > 5 ? console.log("finished") : myself(x + 1) };

通过这种方式,您可以将函数重新分配给任何变量。同时,我们确保函数始终调用自身,而不是将某些函数分配给变量 f1

This way you can reassign the function to any variable as many times you want. At the same time, we ensured that the function always calls itself, and not some function assigned to the variable f1.

所以对最初问题的答案是:你以这种方式定义递归函数,因为它是最灵活和最健壮的方式。

So the answer to the initial question: you define recursive functions in this manner, because it is the most flexible and robust way.

这篇关于递归|两个函数名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆