Chromata
Chromata

Reputation: 47

Why does having [].map with curly brackets change the way it works?

So, basically I have this:

Array.prototype.toString = function() {
    return ("[" + this.map(thing => thing = '"' + thing + '"').join(', ') + "]")
}

When I call it:

['foo', 'bar'].toString()

It returns

"["foo", "bar"]"

Now, THAT would work perfectly. This one (with curly brackets) doesn't seem to work like I wanted it to:

Array.prototype.toString = function() {
    return ("[" + this.map(thing => {thing = '"' + thing + '"'}).join(', ') + "]")
}

and it returns:

[, ]

So can someone tell me the difference? I don't know why [].map works like this.

Upvotes: 3

Views: 3101

Answers (4)

Rhumborl
Rhumborl

Reputation: 16609

Because when you add {}, it turns it from a pure functional-style arrow function into a normal function, just it has arrow syntax. If you want to return a value from this, you need to explicitly write return thing; at the end:

Array.prototype.toString = function() {
    return ("[" + this.map(thing => {thing = '"' + thing + '"'; return thing;}).join(', ') + "]")
}

The reason the pure arrow function works is because the statement thing = '"' + thing + '"' actually returns the result, and hence is the return value of the function. You could get exactly the same result without reassigning thing:

Array.prototype.toString = function() {
    return ("[" + this.map(thing => '"' + thing + '"').join(', ') + "]")
}

Upvotes: 0

Quentin
Quentin

Reputation: 943537

This has nothing to do with arrays or the map method. It is entirely about how arrow functions work.

When you give a single statement on the right hand side, then that statement is evaluated and returned inside the function.

foo => bar

is equivalent to:

function (foo) { return bar; }

When you put a block on the right hand side, that block simply because the function body.

foo => { bar }

is equivalent to:

function (foo) { bar; }

In this second version, you have no return statement, so the function returns undefined.

You need to make the return statement explicit if you use a block.

foo => { return bar; }

Upvotes: 8

Nina Scholz
Nina Scholz

Reputation: 386570

You do not return something in the block statement of the arrow function

() => {
    // code
    return 42; // return is required in block statment
}


() => 42 // return is implicit

Array.prototype.toString = function() {
    return ("[" + this.map(thing => { return thing = '"' + thing + '"'}).join(', ') + "]")
};

console.log(['foo', 'bar'].toString())

Shorter, without assignment to thing

Array.prototype.toString = function() {
    return ("[" + this.map(thing => '"' + thing + '"').join(', ') + "]")
};

console.log(['foo', 'bar'].toString())

Upvotes: 3

Jayce444
Jayce444

Reputation: 9063

Without curly braces (or with regular curved brackets) it returns a single value straight up, whereas curly braces execute multiple lines of code. If you want this code to return a value you have to explicitly return it within those curly braces.

Upvotes: 0

Related Questions