rgb_jewel
rgb_jewel

Reputation: 81

Returning Values in Javascript Functions

I came across this answer while understanding closures by @Jacob Swartwood https://stackoverflow.com/a/6472397/3179569

and I could not understand how littleGirl called story as if it was a function. Shouldn't it have been littleGirl(); so that the princess function was called? Also isn't the princess function returning a key value pair, which means it's returning an object? So how can littleGirl access a key as if it was a function? (because story is a key right?)

I tried searching for the term returning a key value pair in javascript but didn't come up with a decent explanation. I'm hoping someone here can help me. I come with a background in Java and C++ so this is a bit confusing.

function princess() {


    var adventures = [];

    function princeCharming() { /* ... */ }

    var unicorn = { /* ... */ },
        dragons = [ /* ... */ ],
        squirrel = "Hello!";


    return {


        story: function() {
            return adventures[adventures.length - 1];
        }
    };
}


var littleGirl = princess();

littleGirl.story();

Upvotes: 2

Views: 61

Answers (3)

FrancescoMM
FrancescoMM

Reputation: 2960

Or in another way, princess is just a function.

You call it with princess() and it returns something.

That something it returns, is an object like this:

{
    story:function() {...}
}

This object has a function (story) inside.

A function is, after all, just some data you can pass around and assign to variables like any other data.

An object is a way of grouping different data together into a single.. well.., object

So you can put functions inside objects. And functions can return any data kind, including objects.

// set variable aFunc to some function
var aFunc=function() {...}

// call it
aFunc();

// Set an object
var anObj= {
    anInt:3,
    aString:"blabla",
    itsFunction:aFunc
}

Call the function inside it

anObj.itsFunction();

A function returning the same object is

function getAnObj() {
    return {
        anInt:3,
        aString:"blabla",
        itsFunction:aFunc
    }
}

In our case, princess is just like getAnObj, story is just like aFunction

So

princess().story();

is just like

var anObj=getAnObj();
anObj.itsFunction();

A function (princess) returned an object (littleGirl) that has a function inside it (story). And you call it.

A function (getAnObj) returned an object (anObj) that has a function inside it (itsFunction). And you call it.

Names..

Upvotes: 1

Davin Tryon
Davin Tryon

Reputation: 67296

Maybe if we break it down and add one thing at a time it will make more sense.

First, a function princess that returns undefined:

function princess() {
}

princess();

//> undefined

Next, a function that returns an object literal:

function princess() {
    return {};
}

princess();

//> Object {}

Next, a function that returns an object literal with a function inside it (which returns undefined):

function princess() {
    return {
        story: function {}
    };
}

princess().story();

//> undefined

Next, a function that returns an object literal with a function inside that returns an array:

function princess() {
    return {
        story: function {
            return [];
        }
    };
}

princess().story();

//> Array []

I think that covers most of your points. However, none of this has much to do with closures. In your example, the array adventures is what is being closed over. This allows kind of a private member (like with access modifier in Java).

So, finally, a function that returns an object literal with a function inside which closes over a private array:

function princess() {
    var myArray = [1, 2, 3];
    return {
        story: function {
            return myArray[myArray.length - 1];  // get the last one: 3
        }
    };
}

princess().story();

//> 3

Upvotes: 4

Marie
Marie

Reputation: 2217

To expand on what @asantaballa said, story is a key with a value of function () {...}. If you were to run console.log(littleGirl.story) you would see function princess/<.story()

Princess could be rewritten like this...

function princess() {


    var adventures = [];

    function princeCharming() { /* ... */ }

    var unicorn = { /* ... */ },
        dragons = [ /* ... */ ],
        squirrel = "Hello!";

    var getAdventure = function () {
        return adventures[adventures.length - 1];
    };

    var retObj = new Object(); // same as '{}'
    retObj.story = getAdventure;

    return retObj;
}


var littleGirl = princess();

littleGirl.story();

Upvotes: 2

Related Questions