admin管理员组

文章数量:1425656

I'm ing from C#/PHP and trying to get my head around Javascript's idea that functions are variables/objects and have quasi constructors, etc.

Can anyone explain why the following code functions as it does, namely:

  1. Why isn't "2" displayed when instantiating the variable/function test?
  2. Why isn't "1" displayed when executing the variable/function test?

code:

var setup = function () {
    console.log(1);
    return function() {
        console.log(2);
    };
};

var test = setup(); // 1
test(); // 2
test(); // 2
test(); // 2

added:

Thanks @thejh @Justin so the function is returning a pletely different function that has nothing to do with the first (I was thinking of the second function as a kind of constructor of the first), if I ment it out, it's clearer:

$(document).ready(function() {

    var setup = function () {
        console.log(1);
//        return function() {
//            console.log(2);
//        };
    };

    var test = setup(); // 1
    test(); // "test is not a function"
    test(); // "test is not a function"
    test(); // "test is not a function"

});

I'm ing from C#/PHP and trying to get my head around Javascript's idea that functions are variables/objects and have quasi constructors, etc.

Can anyone explain why the following code functions as it does, namely:

  1. Why isn't "2" displayed when instantiating the variable/function test?
  2. Why isn't "1" displayed when executing the variable/function test?

code:

var setup = function () {
    console.log(1);
    return function() {
        console.log(2);
    };
};

var test = setup(); // 1
test(); // 2
test(); // 2
test(); // 2

added:

Thanks @thejh @Justin so the function is returning a pletely different function that has nothing to do with the first (I was thinking of the second function as a kind of constructor of the first), if I ment it out, it's clearer:

$(document).ready(function() {

    var setup = function () {
        console.log(1);
//        return function() {
//            console.log(2);
//        };
    };

    var test = setup(); // 1
    test(); // "test is not a function"
    test(); // "test is not a function"
    test(); // "test is not a function"

});
Share Improve this question edited Dec 16, 2010 at 15:49 Edward Tanguay asked Dec 16, 2010 at 15:38 Edward TanguayEdward Tanguay 194k321 gold badges725 silver badges1.1k bronze badges 3
  • Heavily discussed here: stackoverflow./questions/1634268/… – Mikhail Commented Dec 16, 2010 at 15:41
  • Not mine, but OOP in JS is a fantastic read to wrap your hand on how the prototype based JS deals with these things. phrogz/js/classes/OOPinJS.html – iivel Commented Dec 16, 2010 at 15:50
  • @your edit The function() syntax is just a prettier way of calling new Function(). So it's perfectly natural and expected that a new Function instance will be created. – Alin P. Commented Dec 16, 2010 at 15:58
Add a ment  | 

6 Answers 6

Reset to default 5

You're only calling setup() the first time. Once it is called, the new function it returns is assigned to test. From there on, you're calling that new function:

// calls setup which logs 1 and returns a new function.
// setup also returns a new function and assigns that new function to test.
var test = setup(); 

// test now is the equivalent of var test = function(){ console.log(2); };

// call the new function that setup returned which logs 2
test();

// and again
test();

// and again
test();

Because you're returning a different function from what gets called when creating it (the one in the return, one you're not calling on the first line)...that's what gets executed on the other calls. For example this would give you 1 then 2:

var test = setup()(); // 1, 2

You can test it here.

In your first assignment of test to setup(), you're executing the whole function, so console.log(1) runs, then returns a new function.

Now, you're assigning the return value of that first function to be the next function that runs console.log(2), so now test references that returned function.

Your subsequent calls just run that function which runs console.log(2)

Calling setup() prints 1 and returns a reference to that anonymous function. Calling that prints 2.

Hello when you do setup() you execute this two lines :

console.log(1);
function() { console.log(2); }
  • the first line log "1"
  • the second line doesn't log any thing, because the function is not called, it only create an object (and this object is a function).

when you do test() you actually call the function you've created and so you log "2"

JS is a functional language, you have to see functions like first citizen object.

Imagine instead of

var setup = function () {
    console.log(1);
    return function() {
        console.log(2);
    }
}

this equivalent OOP syntax

var setup = new Function("\
    console.log(1);\
    return new Function(\"\
        console.log(2);\
    \");\
");
var test = setup(); // 1
test(); // 2
test(); // 2
test(); // 2

I think things should be more familiar to you now.

本文标签: