开发者

Ambiguous function declaration in Javascript

I am new to Javascript and got confused by how the function declaration works. I made some test on that and got some interesting results:

say();

function say()
{
    alert("say");
}

The forward-declaration worked and popup "say"

On the opposite

say();

sa开发者_如何学JAVAy = function()
{
    alert("say");
}

did not work, although it also declared a function object

If we declare the function and redeclare that afterwards:

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

I got "say" instead of "speak". That's surprise!

OK. It seems that only the latest function declaration works. Then lets declare function object first and then a "regular" function:

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

Another surprise, it was "speak" followed by "speak". The "regular" function declaration did not work at all!

Is there an explanation of all of them? And, if the "regular" function declaration is really that "fragile" and can be easily override by the function object with same name, should I stay away from that?

Another question is: with only the function object format, does that forward-declaration become impossible? Is there any way to "simulate" that in Javascript?


Javascript works like this:

The document is parsed, and the function declarations are all taken taken into account immediately, before the execution of the actual statements occur. This explains your first example.

If you assign a function to a local variable, that is done during the execution, so you can't use the method in your second example.

What you experience is that if you declare a function twice, the last one will be used by the entire application. That's your third example.

These functions are made members of the window object, they are in effect declared globally. If you assign a local variable to a value of a function, then that local variable takes precedence over members in the window object. If javascript can't find a local variable, it searches up in scope to find it, the window object being the last resort. That's what happened in your last example, it has a variable say that is in a more specific scope than the global function say.

If you would redeclare say at runtime, i.e. swap the order of declarations in your last example, then you would see the two different alerts you'd expect:

say(); //speak, the global function

function say() {
  alert('speak');
}

var say = function() {
  alert('say');
}

say(); //say, the declared local variable


say();

function say()
{
    alert("say");
}

Here the interpreter fetches the definition of say() when it is called, and executes it.

say();

say = function()
{
    alert("say");
}

Here there is no definition of say() to fetch - instead you are assigning an anonymous function to a variable. The interpreter can't "find" this like it can find forward declarations.

function say()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

Here say is defined and then redefined - the last definition wins out.

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

say();

Here say is a variable pointing to an anonymous function (after the first statement is interpreted). This takes precedence over any function definition, the same as if you had placed the function definition before the assignment.

But if you had

say();

say = function()
{
    alert("speak");
}

say();

function say()
{
    alert("say");
}

Then you would get "say" followed by "speak".


You can expect your function definitions to be applied in order. Then all of your non-method lines of code will be executed in order, including the assignment of function objects. This explains each of your examples. It is an interesting issue though. You really can't assign a function object after attempting to call it, and expect it to work. However, a function definition that follows executable code will actually be applied first.


Its always good idea calling the function later, even though javascript works like that.

Most of the languages won't work that way, instead do this.

function say(){
    alert("say");
}

say();

or

say = function(){
    alert("say");
}

say();

or

(function(){
    alert("say");
})();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜