Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 635
Algorythmis Avatar asked Feb 05 '17 14:02

Algorythmis


1 Answers

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

like image 76
haim770 Avatar answered Sep 17 '22 18:09

haim770