Algorythmis
Algorythmis

Reputation: 672

Array.prototype.map(callback, thisArg), second argument ignored

I'm using Node.js to write a little game which I want to be available in two different languages.

In order to show the translated lists of the different gamemodes and their respective descriptions, I am using Array.prototype.map(callback, thisArg), but it looks like Node ignores the thisArg argument :

sendMessage(translated[channel.id].modeList + modes.filter(a => {
    if (typeof a === "string")
        return true;
    return false;
}).map(translated.modeDesc, translated[channel.id]).join("\n"));

translated :

const translated = {
    "chooseLang" : "Choose a language",
    "invalidOption" : "Invalid option",
    "modeDesc" : mode => {return mode + " : " + "<" + modes[0][mode].join("|") + ">\n = " + this.modeDescs[mode];},
    "(channel id)" : global.en
};

global.en :

const en = {
    "modeList" : "Here is a list of available gamemodes :",
    "modeDescs" : {
        "mode" : "description"
    }
};

It looks like Node is trying to use translated.modeDescs, which does not exist, instead of translated[channel.id].modeDescs (global.en.modeDescs) :

TypeError: Cannot read property 'mode' of undefined
    at Object.ruleDesc (/home/algorythmis/Documents/Game/main.js:89:111)
    at Array.map (native)
    ...

So, is Node really ignoring thisArg or am I just in the wrong way? And what can I do to have the behavior I want to?

Thanks in advance.

Upvotes: 5

Views: 5358

Answers (1)

haim770
haim770

Reputation: 49095

When using arrow function, the lexical scope is preserved so this is referring to the context in which translated object has defined in, not the the actual object that holds the reference to the function.

Try to use a regular function:

"modeDesc" : function(mode) {return mode + " : " + "<" + modes[0][mode].join("|") + ">\n = " + this.modeDescs[mode];}

Or use call to explicitly set the context:

var data = translated[channel.id].modeList + modes.filter(a => { ... });
data = Array.prototype.map.call(translated, translated.modeDesc);

sendMessage(data);

See MDN

Upvotes: 6

Related Questions