Categories
JavaScript Interview Questions

JavaScript Interview Questions — Objects

To get a job as a front end developer, we need to nail the coding interview.

In this article, we’ll look at some object questions.

How to check if a certain property exists in an object?

There’re a few ways to check if a property exists in an object.

First, we can use the in operator. For example, we can use it as follows:

const foo = { a: 1 };
console.log('a' in foo);

The in operator checks if the property with the given name exists in the object itself or its prototypes in the prototype chain.

The code above should return true since a is a property of foo .

console.log(‘toString’ in foo); should also log true since toString is in the Object ‘s prototype, which foo inherits from.

We can also use the Object.prototype.hasOwnProperty method. For example, we can use it as follows:

const foo = { a: 1 };
console.log(foo.hasOwnProperty('a'));

The code above uses the hasOwnProperty method in foo ‘s prototype to check if a exists in foo and its own property, which means that it’s in foo itself rather than its prototype.

The console.log logs true since a is foo ‘s own property.

Finally, we can check using the bracket notation as follows:

const foo = {
  a: 1
};
console.log(foo['a']);

If it returns the value other than undefined , then we know we added it as a property.

Since this is the case with our example, it should return true .

What’s the difference between Object.seal and Object.freeze methods?

After calling Object.seal on an object, we stop properties from being added to the object.

It also makes all existing properties non-configurable, which means the property descriptors are prevented from changing.

Existing properties also can’t be removed with the delete operator after it’s called on an object.

The object’s __proto__ property, which is the object’s prototype, is also sealed.

For example, if we have:

const foo = {
  a: 1
};
Object.seal(foo);
delete foo.a

We’ll still see foo.a after we run the last line.

If we’re in strict mode, we’ll get an error.

Object.freeze makes the object immutable. Existing properties can’t be changed in any way, including the values of each property.

It also does everything that Object.seal does.

What’s the difference between the in operator and the hasOwnProperty method in objects?

The in operator checks if a property is in the object itself and if it’s in its prototypes up the prototype chain.

On the other hand, hasOwnProperty only checks if an object is inside the object that it’s called on and not any of its prototypes.

Why does typeof null return object?

null has type object because it’s how it acts in early versions of JavaScript. It just stays this way to prevent breaking existing codebases.

How to check if a value is null?

We should use the strict equality operator to check for null as follows:

foo === null

What does the new keyword do?

The new keyword is used to create an object from constructor functions or classes.

For example, if we have a Person class:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
};

Then we can create a new instance of it by writing:

const person = new Person("Jane", "Smith");

new does a few things:

  • It creates an empty object
  • Assigns the empty object to the this value
  • The function inherits from the prototype property of the constructor function. So Person inherits from Person.prototype .
  • If there’s no return statement in the function, then it’ll return this .

Note that the class syntax in ES2015 or later is just syntactic sugar for constructor functions. It does the same thing but looks like a class.

Conclusion

We can check if a property exists in an object with the in operator, hasOwnProperty , or bracket notation.

Object.seal prevent property descriptors from changing and properties from being deleted.

Object.freeze makes an object immutable.

null is of type object rather than having its own type.

The new keyword makes a new object from a constructor function and returns it.

Categories
JavaScript Interview Questions

JavaScript Interview Questions — Functions and Objects

Why Does foo.bar.baz Property Throw an Error?

If the bar property or bar.baz property is undefined or null or it doesn’t exist, then we will get an error indicating that either one is undefined or null .

Also, the object’s prototype also doesn’t have the property or is undefined or null .

We should check that these properties exist and isn’t null or undefined so that the code doesn’t throw an error.

What is the prototype of an object?

The prototype of an object is the template for an object. It’s used as a fallback of properties and methods if they don’t exist on the object itself.

Objects inherit properties and methods from their prototype in JavaScript.

For example, the following object:

const obj = {};
console.log(obj.__proto__)

has a prototype as defined by the __proto__ property. In the console.log output, we should see various properties and methods logged, like toString , toLocaleString , etc.

The JavaScript interpreter will search for properties and methods with the identifier we indicated into the code by searching the object, and up the prototype chain, until it exhausted all the prototypes in the prototype chain.

All objects ultimately inherit from Object.prototype .

What is an IIFE and what do we use it for?

IIFE stands for Immediately Invoked Function Expression. It’s a function that we defined on the fly and then run it immediately.

We do this by wrapping the function expression inside parentheses and then add the parentheses in the end to call that function.

An IIFE looks like:

(function () {

}());

or:

(() =>{

})();

The function can also be named if we write the following traditional function:

(function foo() {

})();

We can also return something from the function and assign it immediately:

const foo = (()=> {
 return 'foo';
})();

Then the value of foo is 'foo' .

We can also pass in arguments like any other function:

const foo = ((a, b)=> {
 return a + b;
})(1,2);

Then foo is 3.

IIFEs are useful for hiding items from the outside before we have modules. Also, it also lets us avoid polluting the global namespace before we have modules.

What is the Function.prototype.apply method?

The apply method lets us call a function with a different value of this and pass in values into the function arguments as an array.

For example, we can write:

function greet(greeting){
 return `${greeting} ${this.name}`;
}

const person = {
 name: 'Jane'
}

console.log(greet.apply(person, ['Hello']));

In the code above, we created a greet function, which takes a greeting argument.

Then we defined a person object with a name property.

We then call greet with the apply method by passing in person as the first argument, which is the value of this that we want in the function. The second argument is an array which we pass into greet as arguments.

In the case, we passed in 'Hello' of as the value of the greeting parameter.

The result of the console.log is Hello Jane .

apply doesn’t work with arrow functions since it doesn’t have its own this value.

What is the Function.prototype.call method?

The call method of a function is very similar to apply , except that we pass in a comma-separated list of arguments to call the function with arguments instead of passing in an array to pass in arguments to the function that call is called on.

For example, we can write the following code:

function greet(greeting){
 return `${greeting} ${this.name}`;
}

const person = {
 name: 'Jane'
}

console.log(greet.call(person, 'Hello'));

As we can see, the only difference between call and apply is whatever is after the first argument.

call doesn’t work with arrow functions since it doesn’t have its own this value.

What is Function.prototype.bind method?

The bind method lets us change the this value inside a function like call and apply .

Like call and apply , we pass in the object that we want to be the value of this inside the function as follows:

function greet(){
 return `${this.name}`;
}

const person = {
 name: 'Jane'
}

const greetPerson = greet.bind(person);
console.log(greetPerson());

bind doesn’t work with arrow functions since it doesn’t have its own this value.

In the code above, we passed person into bind , so this.name would be 'Jane' . We can assign the function returned by bind to a new variable or constant. Then we can call it as we did as we have above.

Therefore, console.log would give us ‘Jane’.

Conclusion

JavaScript programs will throw errors if we try to access a property when a parent’s property doesn’t exist.

IIFEs are functions that are created on the fly and then called right after it’s defined.

The call and apply methods let us call functions with a different this value and arguments that we pass in. bind lets us change the this value inside the function. Then we can call the returned function that has a different this value and then call it.

Categories
JavaScript Interview Questions

JavaScript Interview Questions — Functions and Objects

To get a job as a front end developer, we need to nail the coding interview.

In this article, we’ll look at some functions and object questions.

What are Arrow Functions?

Arrow functions are a new way to define functions in JavaScript. It’s available since ES2015.

It takes away the confusion with this since it doesn’t bind to this and so they can’t be used as constructor functions.

They also can’t be hoisted, so they can only be used after they’re defined.

Also, they don’t bind to the arguments object, so we can’t get the arguments that are passed into arrow functions with it like in function declarations.

To get arguments from an arrow function, we use the rest syntax as follows:

const getArgs = (...rest) => rest

For example, we can define an arrow function as follows:

const currentDate = () => new Date();

In the code above, we defined the arrow function with => and returns new Date() to return the current date.

If we want to return something in a multi-line arrow function, we have to write return explicitly like any other function.

For example, we can write:

const currentDate = () => {
  return new Date();
}

to return new Date() explicitly in a multi-line arrow function.

We can pass in parameters like any other function as follows:

const identity = (obj) => {
  return obj;
}

What are Classes?

In JavaScript, classes are syntactic sugar for constructor functions. It’s used to create instances of a class but hides the prototype manipulations from our view.

Underneath, it still uses the prototype inheritance model that it has always been using.

For example, if we have the following chain of classes:

class Person {
  constructor(firstName, lastName) {
    this.lastName = lastName;
    this.firstName = firstName;
  }

  fullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

class Employee extends Person {
  constructor(firstName, lastName, title) {
    super(firstName, lastName);
    this.title = title;
  }

  getTitle() {
    return this.title;
  }
}

In the code above we have the Person class with a constructor and a method to get the full name.

Then we have the Employee class that extends the Person class as we indicated with the extends keyword.

In the constructor, we call the Person class’s constructor and also set the title field, which is exclusive to Employee.

We also added a getTitle method.

The JavaScript interpreter will give us an error if we forgot to call the super function.

This is the same as the following code, written with constructor functions:

function Person(firstName, lastName) {
  this.lastName = lastName;
  this.firstName = firstName;
}

Person.prototype.fullName = function() {
  return `${this.firstName} ${this.lastName}`;
}

function Employee(firstName, lastName, title) {
  Person.call(this, firstName, lastName);
  this.title = title;
}

Employee.prototype = Object.create(Person.prototype);

Employee.prototype.getTitle = function() {
  return this.title;
}

The code above is the same as what we had with the classes, except that we get no errors if Person.call or Object.create was missing.

We also have to add things to the prototype of each constructor function outside the function.

Even though we don’t use the constructor function syntax, we have to know that the class syntax is just syntactic sugar for constructor functions.

What is Object Destructuring?

Object destructuring is a clean way to assign array entries or object properties into their own variables.

For example, we can use it to decompose array entries to individual variables as follows:

const [one, two] = [1, 2];

Then one is 1 and two is 2.

The code above is the same as:

const arr = [1, 2];
const one = arr[0];
const two = arr[1];

Likewise, we can do the same with an object as follows:

const {
  one,
  two
} = {
  one: 1,
  two: 2
}

Then the one property’s value is assigned to one , and two ‘s value is assigned to two .

The code above is the same as:

const obj = {
  one: 1,
  two: 2
}
const one = obj.one;
const two = obj.two;

As we can see, object and array destructuring is much cleaner than the old way.

We can also set variables to default values by writing:

const [one, two, three = 3] = [1, 2];

Then since three has not array entry assigned to it, three has a value of 3.

Conclusion

Arrow functions are useful for creating functions that aren’t constructor functions. They don’t bind to this. Also, it’s shorter since we don’t have to write return to return something if it’s one line.

Classes in JavaScript are syntactic sugar for constructor functions. It lets us do inheritance and create instance methods easier since we don’t have to manipulate prototypes directly and the JavaScript interpreter will give us errors if we missed anything.

Object and array destructuring let us assign object or array entries into variables in a clean way.

Categories
JavaScript Interview Questions

JavaScript Interview Questions — Arrays

To get a job as a front end developer, we need to nail the coding interview.

In this article, we’ll look at some JavaScript array questions.

Implement the Array.prototype.map method by hand.

The Array.prototype.map method maps each array entry to new entry by calling a callback function to do the mapping.

It returns a new array with the mapped values.

We can implement it as follows:

const map = (arr, callback) => {
  if (!Array.isArray(arr)) {
    return [];
  }
  const newArr = [];
  for (let i = 0, len = arr.length; i < len; i++) {
    newArr.push(callback(arr[i], i, arr));
  }
  return newArr;
}

First, we check if arr is an array, we return an empty array if it’s not.

In the code above, we have the map method that loops through each array entry and calls a callback with the array entry, index, and the original array passed in. Each entry is pushed to newArr array.

Then it returns the newArr array, which has the mapped entries.

Implement the Array.prototype.filter method by hand.

The Array.prototype.filter method returns a new array that takes the elements from the original array that meets the predicate in a callback, push those entries into a new array, then returns it.

We can implement that as follows:

const filter = (arr, callback) => {
  if (!Array.isArray(arr)) {
    return [];
  }
  const newArr = [];
  for (let i = 0, len = arr.length; i < len; i++) {
    if (callback(arr[i], i, arr)) {
      newArr.push(arr[i]);
    }
  }
  return newArr;
}

In the code above, we first check if arr is an array. We return an empty array if it’s not.

Then we loop through arr and then use an if block to check if the callback call returns true , then we push those entries to newArr and returns it.

Implement the Array.prototype.reduce method by hand.

The Array.prototype.reduce method combines an array’s entry into one by calling a callback repeatedly to combine the array entries into one value.

For example, we can write the following:

const reduce = (arr, reduceCallback, initialValue) => {
  if (!Array.isArray(arr)) {
    return;
  }
  let val = initialValue || 0;
  for (let i = 0, len = arr.length; i < len; i++) {
     val = reduceCallback(val, arr[i]);
  }
  return val;
}

We first check if arr is an array, then we return if it’s not an array.

Then we set val to initialValue if it exists or 0.

Next, we loop through the array and then use the reduceCallback to combine val and arr[i] and returns the new value and assign it to val .

Once the loop is done, we return val .

What’s the arguments object?

The arguments object is an array-like object that returns the arguments that are passed into a traditional function.

It doesn’t work with arrow functions.

It’s an array-like object because its entries can be accessed by indexes and it has a length property. arguments has no array methods.

Also, it can be looped through by the for...of loop and be converted to an array with the spread operator.

For example, if we write:

function logArgs() {
  console.log(arguments)
}

logArgs(1, 2, 3, 4, 5);

Then we see something like:

Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]

from the console.log .

We can see the entries and the Symbol.iterator method, so we know it’s an iterable object.

We can convert it to an array using the spread operator as follows:

function logArgs() {
  console.log([...arguments])
}

logArgs(1, 2, 3, 4, 5);

Then the console.log gives [1, 2, 3, 4, 5] , which is a regular array.

For arrow functions, we use the rest operator to get all the arguments as follows:

const logArgs = (...args) => {
  console.log(args)
}

logArgs(1, 2, 3, 4, 5);

We see [1, 2, 3, 4, 5] logged.

How do you add an element at the beginning of an array?

We can use the Array.prototype.unshift method to add an element to the beginning of an array.

For example, we can write:

const arr = [2, 3, 4];
arr.unshift(1);

Then arr is [1, 2, 3, 4] .

The spread operator also works for this:

let arr = [2, 3, 4];
arr = [1, ...arr];

Note that we changed const to let since we assigned to a new value.

How do you add an element at the end of an array?

We can use the push method to do add an entry to the end of an array.

For example, we can write:

const arr = [2, 3, 4];
arr.push(1);

Then arr is [2, 3, 4, 1] .

The spread operator also works for this:

let arr = [2, 3, 4];
arr = [...arr, 1];

Note that we changed const to let since we assigned to a new value.

Conclusion

We learn more about JavaScript arrays by implementing the array methods from scratch and practice doing common operations with them.

Categories
JavaScript Interview Questions

JavaScript Interview Questions — Data Types

To get a job as a front end developer, we need to nail the coding interview.

In this article, we’ll look at how some data type questions, including some trick questions that are often asked in interviews.

What are the falsy values in JavaScript?

In JavaScript, falsy values are the following

  • ''
  • 0
  • null
  • undefined
  • false
  • NaN

They become false when they’re converted to a boolean value.

How to check if a value is falsy?

Use the !! operator or Boolean function to check if they’re falsy.

If a value is falsy, then both will return false.

For example:

!!0

will return false.

Boolean(0)

will also return false.

What are truthy values?

Truthy values are any other than those falsy values listed above.

What are Wrapper Objects?

Wrapper objects are objects that are created from constructors that return primitive values but have the type 'object' if it’s a number or a string. Symbols and BigInt have their own types.

In JavaScript, there’s the Number, String constructors, and Symbol, and BigInt factory functions.

Primitive values are temporarily converted to wrapper objects to call methods.

For example, we can write:

'foo'.toUpperCase()

Then we get 'FOO'. It works by converting the 'foo' literal to an object and then call the toUpperCase() method on it.

We can also create wrapper objects for numbers and BigInt as follows:

new Number(1)
BigInt(1)

Using the Number or String constructor directly isn’t too useful, so we should avoid it. They give us the type of object but has the same content as their primitive counterparts.

If we did create Number and String wrapper objects with the new operator as follows:

const numObj = new Number(1);
const strObj = new String('foo');

We can return the primitive value version of those wrapper objects by using the valueOf method as follows:

numObj.valueOf();
strObj.valueOf();

What is the difference between Implicit and Explicit Coercion?

Implicit coercion means that the JavaScript interpreter converts a piece of data from one type to another without explicitly calling a method.

For example, the following expression are implicitly converted to a string:

console.log(1 + '2');

Then we get:

'12'

returned because 1 is converted to '1' implicitly.

Another example would be:

true + false

We get 1 returned because true is converted to 1 and false is converted to 0 and they’re added together.

The following example:

3 * '2'

returns 6 because '2' is converted to 2 and then they’re multiplied together.

The full list of JavaScript coercion rules are here.

Explicit conversion is done by calling a method or using an operator to convert a type.

We can see the coercion done in the code.

For example:

+'1' + +'2'

gets us 3 since we have '1' and '2' are both converted to numbers by the unary + operator.

We can also do the same things with functions. For example, we can use the parseInt function instead of using the unary + operator.

We can rewrite the expression above to:

parseInt('1') + parseInt('2')

Then we get the same result.

What Does 0 || 1 Return?

Since 0 is falsy, it’ll trigger the second operand to run, which gives us 1. Therefore, it should return 1.

What Does 0 && 1 Return?

Since 0 is falsy, it’ll stop running since we have short-circuited evaluation. Therefore, we get 0 returned.

What Does false == ‘0’ Return?

false is falsy and '0' is converted to 0, which is falsy, so they are the same in terms of the ==’s comparison criteria. Therefore, we should get true returned.

What Does 4 < 5 < 6 Return?

In JavaScript, comparisons are done from left to right. So first 4 < 5 will be evaluated, which gives us true . Then true < 6 is evaluated, which is converted to 1 < 6 which is also true .

Therefore, we get true returned.

What Does 6 > 5 > 4 Return?

In JavaScript, comparisons are done from left to right. So 6 > 5 will be evaluated first. This gives us true . Then true > 4 is evaluated, which is converted to 1 > 4 , which is false .

Therefore, the expression returns false .

What Does typeof undefined == typeof null Return?

typeof undefined returns 'undefined' and typeof null returns 'object' .

Since 'undefined' does equal 'object' , the expression should be false .

What Does typeof typeof 10 Return?

JavaScript evaluates typeof typeof 10 as typeof (typeof 10) . Therefore, this returns typeof 'number' , which returns 'string' since 'number' is a string.