两个函数在JavaScript中具有相同的名称 - 这怎么能工作? [英] Two functions with the same name in JavaScript - how can this work?

查看:190
本文介绍了两个函数在JavaScript中具有相同的名称 - 这怎么能工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AFAIK function foo(){aaa(); } 在JavaScript中只是 var foo = function(){aaa()} 所以添加 functtion foo(){bbb(); } 应该覆盖 foo 变量,或忽略第二个定义 - 这不是点。这是事实,应该有一个变量 foo

AFAIK function foo() { aaa(); } is just var foo = function(){ aaa() } in JavaScript. So adding functtion foo() { bbb(); } should either overwirte the foo variable, or ignore the second definition - thats not the point. That's the fact that there should be one variable foo.

因此,在这个例子中 可以从方法中进行核心解析,而且它不在Explorer 8中: - )。我来到这个例子,试图将它们包装到另一个闭包( var 将是,惊讶的是没有必要:

So, in this example the me variable shoudl not be corectly resolved from inside the methods and it is not in Explorer 8 :-). I came to this example by trying to wrap them into another closure where (var) me would be, but I was surprised that it's not necessary:

    var foo = {
        bar1 : function me() {
            var index = 1;
            alert(me);
        },
        bar2 : function me() {
            var index = 2;
            alert(me);
        }    
    };

    foo.bar1(); // Shows the first one
    foo.bar2(); // Shows the second one

DEMO http://jsfiddle.net/W5dqy/5/

推荐答案


AFAIK函数foo(){aaa(); }在JavaScript中只是var foo = function(){aaa()}。

AFAIK function foo() { aaa(); } is just var foo = function(){ aaa() } in JavaScript.

JavaScript有两个不同但相关的东西:函数声明和函数

That's actually incorrect. JavaScript has two different but related things: Function declarations, and function expressions. They happen at different times in the parsing cycle and have different effects.

这是一个函数

function foo() {
    // ...
}

在执行任何逐步代码之前,函数声明在进入封闭范围时被处理。

Function declarations are processed upon entry into the enclosing scope, before any step-by-step code is executed.

这是一个函数 (具体来说,是一个匿名的):

This is a function expression (specifically, an anonymous one):

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

函数表达式作为逐步代码的一部分, (就像任何其他表达式一样)。

Function expressions are processed as part of the step-by-step code, at the point where they appear (just like any other expression).

您引用的代码使用了一个命名函数表达式,其格式如下:

Your quoted code is using a named function expression, which look like this:

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

(在你的情况下,它在一个对象字面量,因此它在一个而不是 = ,但它仍然是一个命名的函数表达式。)

(In your case it's within an object literal, so it's on the right-hand side of an : instead of an =, but it's still a named function expression.)

这是完全有效的,忽略实现bug(稍后更多)。它创建一个名为 foo 的函数,不会 foo scope,然后将该函数分配给 x 变量(当在分步代码中遇到表达式时,会发生这种情况)。当我说它不把 foo 放在封闭范围中,我的意思是:

That's perfectly valid, ignoring implementation bugs (more in a moment). It creates a function with the name foo, doesn't put foo in the enclosing scope, and then assigns that function to the x variable (all of this happening when the expression is encountered in the step-by-step code). When I say it doesn't put foo in the enclosing scope, I mean exactly that:

var x = function foo() {
    alert(typeof foo); // alerts "function" (in compliant implementations)
};
alert(typeof foo);     // alerts "undefined" (in compliant implementations)

注意这与函数的方法不同>

Note how that's different from the way function declarations work (where the function's name is added to the enclosing scope).

命名的函数表达式在兼容的实现上工作。历史上,实现中存在错误(早期Safari,IE8和更早版本)。现代实现让他们正确,包括IE9和更高版本。 (更多此处: <双击 和此处: 命名的函数表达式已解析 。)

Named function expressions work on compliant implementations. Historically, there were bugs in implementations (early Safari, IE8 and earlier). Modern implementations get them right, including IE9 and up. (More here: Double take and here: Named function expressions demystified.)


所以,在这个例子中, me 变量shoudl不能从方法内部进行核心解析

So, in this example the me variable shoudl not be corectly resolved from inside the methods

其实应该是。函数的真实名称( function 和开始括号之间的符号)始终位于函数内部(无论函数是来自声明还是命名函数表达式)。

Actually, it should be. A function's true name (the symbol between function and the opening parenthesis) is always in-scope within the function (whether the function is from a declaration or a named function expression).

由于实现错误,我曾经避免使用命名函数表达式。你可以在你的示例中通过删除 me 名称,但我更喜欢命名函数,所以为什么值,下面是我用来写你的对象:

Because of implementation bugs, I used to avoid named function expressions. You can do that in your example by just removing the me names, but I prefer named functions, and so for what it's worth, here's how I used to write your object:

var foo = (function(){
    var publicSymbols = {};

    publicSymbols.bar1 = bar1_me;
    function bar1_me() {
        var index = 1;
        alert(bar1_me);
    }

    publicSymbols.bar2 = bar2_me;
    function bar2_me() {
        var index = 2;
        alert(bar2_me);
    }

    return publicSymbols;
})();

(除了我可能使用比 publicSymbols 。)

(Except I'd probably use a shorter name than publicSymbols.)

以下是处理方式:


  1. 当在分步代码中遇到 var foo = ... 行时会创建匿名封闭函数,然后调用它(因为我有<$

  2. 在进入由该匿名函数创建的执行上下文时, bar1_me处理 bar2_me 函数声明,并将那些符号添加到匿名函数内的范围(技术上,到 variable object
  3. $ s $ b
  4. publicSymbols 符号被添加到匿名函数中的作用域。 (详情: 差误解 var

  5. 分步骤程式码以 {} publicSymbols

  6. 分步代码继续 publicSymbols.bar1 = bar1_me; publicSymbols.bar2 = bar2_me; ,最后 return publicSymbols;

  7. 匿名函数的结果分配给 foo

  1. An anonymous enclosing function is created when the var foo = ... line is encountered in the step-by-step code, and then it is called (because I have the () at the very end).
  2. Upon entry into the execution context created by that anonymous function, the bar1_me and bar2_me function declarations are processed and those symbols are added to the scope inside that anonymous function (technically, to the variable object for the execution context).
  3. The publicSymbols symbol is added to the scope inside the anonymous function. (More: Poor misunderstood var)
  4. Step-by-step code begins by assigning {} to publicSymbols.
  5. Step-by-step code continues with publicSymbols.bar1 = bar1_me; and publicSymbols.bar2 = bar2_me;, and finally return publicSymbols;
  6. The anonymous function's result is assigned to foo.

,但是,除非我写代码,我知道需要支持IE8(可悲的是,当我在2015年11月写这个仍然有重要的全球市场份额,但令人高兴的是,这份份额正在下降),我不担心。

These days, though, unless I'm writing code I know needs to support IE8 (sadly, as I write this in November 2015 it still has significant global market share, but happily that share is plummetting), I don't worry about it. All modern JavaScript engines understand them just fine.

你也可以这样写:

var foo = (function(){
    return {
        bar1: bar1_me,
        bar2: bar2_me
    };

    function bar1_me() {
        var index = 1;
        alert(bar1_me);
    }

    function bar2_me() {
        var index = 2;
        alert(bar2_me);
    }
})();

...因为这些是函数声明,因此被提升。我通常不这样做,因为我发现更容易做大型结构上的维护,如果我做的声明和属性相邻的属性分配(或者,如果不是为IE8写在同一行上) 。

...since those are function declarations, and thus are hoisted. I don't usually do it like that, as I find it easier to do maintenance on large structures if I do the declaration and the assignment to the property next to each other (or, if not writing for IE8, on the same line).

这篇关于两个函数在JavaScript中具有相同的名称 - 这怎么能工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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