Typical JavaScript interview exercises (explained)

Maxence Poutord on August 24, 2017

Few weeks ago I found on my twitter feed a very interesting blog post: "The Best Frontend JavaScript Interview Questions (written by a Frontend E... [Read Full]
markdown guide
 
const newHeroes = heroes.map(h => {
  return {
    ...h,
    name: h.name.toUpperCase()
  }
})
 
 

I've been writing for about a decade now, but didn't know about that it is possible to bind functions to objects like this:

let dog = {
   sayName () {
    console.log(this.name)
  }
}

Is this a relatively new thing or it has always worked like this? Are there any reference material on this?

 
const heroes = [
  { name: 'Wolverine',      family: 'Marvel',    isEvil: false },
  { name: 'Deadpool',       family: 'Marvel',    isEvil: false },
  { name: 'Magneto',        family: 'Marvel',    isEvil: true  },
  { name: 'Charles Xavier', family: 'Marvel',    isEvil: false },
  { name: 'Batman',         family: 'DC Comics', isEvil: false },
  { name: 'Harley Quinn',   family: 'DC Comics', isEvil: true  },
  { name: 'Legolas',        family: 'Tolkien',   isEvil: false },
  { name: 'Gandalf',        family: 'Tolkien',   isEvil: false },
  { name: 'Saruman',        family: 'Tolkien',   isEvil: true  }
];

function copyObject(obj, cb) {
  let callbackPassed = false,
      stringToObj = null,
      objToString = null;

  if (cb && typeof cb !== "function") throw new Error("Second Argument must be function.");
  else callbackPassed = true;

  objToString = JSON.stringify(obj);
  stringToObj = JSON.parse(objToString);

  if (callbackPassed) cb(stringToObj);

  return stringToObj;
}


const newHeroes = heroes.map(h => {
  return copyObject(h, function (obj) {
    obj.name = obj.name.toUpperCase();
  });
});
// you can copy Objects with JSON :)
// Object.assign is better solution for this kind of problems.

 

This is dirty, right? 🤠

Maybe, but explain why. The second version has been used ad nauseam by React developers who had to bind the component's prototype methods to the component's instance in order to use them nicely in their JSX templates.

The real ugliness here is that object methods lose their context so easily - but it's also one of the best part of JavaScript, since this makes functions as first class objects.

Which means I can do something like this:

class Cat() {
  meow() { ... }
}
const mittens = new Cat('Mittens');
mittens.bark = fido.bark;
mittens.bark(); // 'Mittens says woof'

You already got good answers for your final question 🙂

 

To be very thorough:

Object.freeze(heroes);
const newHeroes = heroes.map(h => {
  Object.freeze(h);
  return { ...h, name: h.name.toUpperCase() }
})
 

Why would you need to freeze it? This stuff is synchronous, how would it change in the middle of your operation?

 

It's to guard against future changes. But the requirement was to "preserve immutability" and so this makes the original data set immutable going forward.

 
const newHeroes = heroes.map(h => {
          return h.name.toUpperCase();
        });
 

Very nice explanation for each scenario. Thanks for the write-up!

 
const newHeroes = heroes.map(h => {
    return Object.assign({}, h, { name: h.name.toUpperCase() });
});
 

deep copy this my approach!!!!
adding this line:
const hr=JSON.parse(JSON.stringify(heroes));
It's work fine

 

I know this was posted a while ago but here is my answer.

heroes.forEach(hero => Object.freeze(hero));

 
 

Very good but very depressing.

I've been at this for a very long time now and... it's time to give up.

 
 

const newHeroes = JSON.parse(JSON.stringify(heroes)).map(h => {
h.name = h.name.toUpperCase()
return h
})

code of conduct - report abuse