Advanced JavaScript - Technical Interview

Ace your homework & exams now with Quizwiz!

Explain what is hoisting in Javascript

Hoisting is JavaScript's default behavior of moving all declarations to the top of the current scope (to the top of the current script or the current function). The variable and function declarations are put into memory during the compile phase, but stay exactly where you typed them in your code. To avoid bugs, always declare all variables at the beginning of every scope. Since this is how JavaScript interprets the code, it is always a good rule.

Closure

"A closure gives you access to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time." "A closure is the combination of a function and the lexical environment within which that function was declared. " **makes it possible for a function to have "private" variables.** var add = (function () { var counter = 0; return function () { counter += 1; return counter } })(); add();

What will the code below output? Explain your answer. console.log(0.1 + 0.2); console.log(0.1 + 0.2 == 0.3);

"You can't be sure." It might print out 0.3 and true, or it might not. Numbers in JavaScript are all treated with floating point precision, and as such, may not always yield the expected results. results: 0.30000000000000004 false

What is NaN? What is its type? How can you reliably test if a value is equal to NaN?

"not a number" but is type Number Best solution: use value !== value, which would only produce true if the value is equal to NaN. Also, ES6 offers a new Number.isNaN() function

What would the following lines of code output to the console? console.log("0 || 1 = "+(0 || 1)); console.log("1 || 2 = "+(1 || 2)); console.log("0 && 1 = "+(0 && 1)); console.log("1 && 2 = "+(1 && 2));

0 || 1 = 1 1 || 2 = 1 0 && 1 = 0 1 && 2 = 2 However, the interesting thing with the && operator is that when an expression is evaluated as "true", then the expression itself is returned. This is fine, since it counts as "true" in logical expressions, but also can be used to return that value when you care to do so. This explains why, somewhat surprisingly, 1 && 2 returns 2 (whereas you might it expect it to return true or 1).

Compare Async/Await and Generators usage to achieve the same functionality

1. Generator functions/yield and Async functions/await can both be used to write asynchronous code that "waits", which means code that looks as if it was synchronous, even though it really is asynchronous. 2. A generator function is executed yield by yield i.e one yield-expression at a time by its iterator (the next method) whereas async-await, they are executed sequential await by await. 3. Async/await makes it easier to implement a particular use case of Generators. 4. The return value of the generator is always {value: X, done: Boolean} whereas for async functions, it will always be a promise that will either resolve to the value X or throw an error. 5. An async function can be decomposed into a generator and promise implementation which is good to know stuff.

What is generator in JS?

A generator is a function that produces a sequence of results instead of a single value, i.e you generate ​a series of values. In short, a generator appears to be a function but it behaves like an iterator. It returns an iterator object on which you can call next(). Every invocation of next() will return an object of shape — { value: Any, done: true | false} The value property will contain the value. The done property is either true or false. When the done becomes true, the generator stops and won't generate any more values.

What is a promise?

A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it's not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending. let promise = new Promise(function(resolve, reject) { // executor (the producing code, "singer") }); In practice, an executor usually does something asynchronously and calls resolve/reject after some time

What is a prototype?

A prototype is an object. When you declare a function, a prototype is created and linked to that function.

The following recursive code will cause a stack overflow if the array list is too large. How can you fix this and still retain the recursive pattern? var list = readHugeList(); var nextListItem = function() { var item = list.pop(); if (item) { // process the list item... nextListItem(); } };

Add timeout function if (item) { // process the list item... setTimeout( nextListItem, 0); } the timeout function (nextListItem) is pushed to the event queue and the function exits, thereby leaving the call stack clear.

What is a potential pitfall with using typeof bar === "object" to determine if bar is an object? How can this pitfall be avoided?

Although typeof bar === "object" is a reliable way of checking if bar is an object, the surprising gotcha in JavaScript is that null is also considered an object! https://www.toptal.com/javascript/interview-questions

Anonymous Functions

An anonymous function is a function without a name. An anonymous function is often not accessible after its initial creation. Because we need to call the anonymous function later, we assign the function to a variable. We often use anonymous functions as arguments of other functions. setTimeout(function () { ... }, 1000); You can create a function and execute it immediately after declaration. (function() { console.log('IIFE'); })();

When should I use Arrow functions in ES6?

Arrow functions are shorthand for declaring anonymous functions Arrow functions are best with: - anything that requires this to be bound to the context, and not the function itself - callbacks or methods like map, reduce, or forEach

What are the benefits, of including 'use strict' at the beginning of a JavaScript source file?

Enforce stricter parsing and error handling on your JavaScript code at runtime. Code errors that would otherwise have been ignored or would have failed silently will now generate errors or throw exceptions.

Explain Promise chaining

Every promise must supply a .then() method with the following signature: Promises allow you to mimic normal synchronous code's try/catch behavior. Like synchronous code, chaining will result in a sequence that runs in serial. In other words, you can do: fetch(url) .then(process) .then(save) .catch(handleErrors); Assuming each of the functions, fetch(), process(), and save() return promises

How does JavaScript inherit methods?

In JavaScript, any function can be added to an object in the form of a property. An inherited function acts just as any other property, including property shadowing as shown above (in this case, a form of method overriding). When an inherited function is executed, the value of this points to the inheriting object, not to the prototype object where the function is an own property. var o = { a: 2, m: function() { return this.a + 1; } }; console.log(o.m()); // 3 // When calling o.m in this case, 'this' refers to o var p = Object.create(o); // p is an object that inherits from o p.a = 4; // creates a property 'a' on p console.log(p.m()); // 5

Explain shallow vs. deep copy of objects in JavaScript.

In JavaScript, you use variables to store values that can be primitive or references. For a primitive value, you just simply use a simple assignment. If you use the assignment operator for a reference value, it will not copy the value. Instead, both variables will reference the same object in the memory. EXAMPLE: let person = { firstName: 'John', lastName: 'Doe' }; let copiedPerson = person; copiedPerson.firstName = 'Jane'; console.log(person); Output: { firstName: 'Jane', lastName: 'Doe' } In the example above, we actually made a shallow copy. A deep copy means that all of the values of the new variable are copied and disconnected from the original variable. A shallow copy means that certain (sub-)values are still connected to the original variable. This is often times problematic, since we expect the old variable to have the original values, not the changed ones. When we access it, we sometimes get an error.

Is JavaScript a pass-by-reference or pass-by-value language?

Javascript is a pass by value language. But for objects, the value is their reference. In javascript mostly arrays and objects follow pass by reference. So for example, if you pass an int to a function as parameter and increment its value in the function, its value will not be updated in the caller's context

arr.filter( item => function );

Returns a filtered array based on some expression. Don't forget to reassign it. arr = arr.filter( item => return item !== value});

Explain the Prototype Design Pattern

The Prototype pattern as one that creates objects based on a template of an existing object through cloning. We can think of the Prototype pattern as being based on prototypal inheritance in which we create objects that act as prototypes for other objects. The prototype object itself is effectively used as a blueprint for each object the constructor creates. If the prototype of the constructor function used contains a property called name for example (as per the code sample that follows), then each object created by that same constructor will also have this same property (Figure 9-6).The Prototype Pattern relies on the JavaScript prototypical inheritance and creates new objects in performance-intensive situations. The Prototype Pattern creates new objects, but rather than creating non-initialized objects it returns objects that are initialized with values it copied from a prototype (or sample object). An example of where the Prototype pattern is useful is the initialization of business objects with values that match the default values in the database. The prototype object holds the default values that are copied over into a newly created business object. JavaScript being a prototypal language uses this pattern in the construction of new objects and their prototypes.

What is the value of typeof undefined == typeof NULL?

The expression will be evaluated to true, since NULL will be treated as any other undefined variable. Note: JavaScript is case-sensitive and here we are using NULL instead of null.

What do the following lines output, and why? console.log(1 < 2 < 3); console.log(3 > 2 > 1);

The first statement returns true which is as expected. The second returns false because of how the engine works regarding operator associativity for < and >. It compares left to right, so 3 > 2 > 1 JavaScript translates to true > 1. true has value 1, so it then compares 1 > 1, which is false.

what does map() do?

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

Consider the code snippet below. What will the console output be and why? (function(x) { return (function(y) { console.log(x); })(2) })(1);

The output will be 1 In JavaScript, a closure is implemented as an "inner function"; i.e., a function defined within the body of another function. An important feature of closures is that an inner function still has access to the outer function's variables. Therefore, in this example, since x is not defined in the inner function, the scope of the outer function is searched for a defined variable x, which is found to have a value of 1.

What does the reduce function do?

The reduce() method reduces the array to a single value. The reduce() method executes a provided function for each value of the array (from left-to-right). The return value of the function is stored in an accumulator (result/total).

What is the significance of, and reason for, wrapping the entire content of a JavaScript source file in a function block?

This is an increasingly common practice, employed by many popular JavaScript libraries (jQuery, Node.js, etc.). This technique creates a closure around the entire contents of the file which, perhaps most importantly, creates a private namespace and thereby helps avoid potential name clashes between different JavaScript modules and libraries.

Inheritance and the prototype chain

When you access a property or method in Javascript. Javascript will check the object to see if that property exists. If it doesn't it will check it's prototype and will continue to walk up the prototype chain until it reaches the Object prototype. The linkages between prototype objects are formed via the __proto__ property. rabbit.__proto__ = animal; // sets rabbit.[[Prototype]] = animal Now if we read a property from rabbit, and it's missing, JavaScript will automatically take it from animal. By definition, null has no prototype, and acts as the final link in this prototype chain. ***The for..in loop iterates over both its own and its inherited properties. All other key/value-getting methods only operate on the object itself.***

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

With ES6, one can use the spread operator: myArray = ['start', ...myArray]; myArray = [...myArray, 'end']; Or, in short: myArray = ['start', ...myArray, 'end'];

Consider the two functions below. Will they both return the same thing? Why or why not? function foo1() { return { bar: "hello" }; } function foo2() { return { bar: "hello" }; }

foo1 returns: Object {bar: "hello"} foo2 returns: undefined The reason for this has to do with the fact that semicolons are technically optional in JavaScript -- but a semicolon is automatically inserted immediately after the return statement ***Follow the convention of placing an opening curly brace at the end of a line in JavaScript, rather than on the beginning of a new line.***

arr.slice();

makes a copy of the array

What would following code return? console.log(typeof typeof 1);

string typeof 1 will return "number" and typeof "number" will return string.

What's the difference between a variable that is: null, undefined or undeclared? How would you go about checking for any of these states?

undefined is a variable that has been declared but no value exists and is a type of itself 'undefined'. null is a value of a variable and is a type of object. We use 'console.log();' and 'type of' to check if a variable is undefined or null. undeclared variables is a variable that has been declared without 'var'

How do you clone an object?

var obj = {a: 1 ,b: 2} var objclone = Object.assign({},obj); To copy an object in JavaScript, you have three options: Use the spread (...) syntax Use the Object.assign() method Use the JSON.stringify() and JSON.parse() methods Both spread (...) and Object.assign() perform a shallow copy while the JSON methods carry a deep copy.


Related study sets

MKT 3360 - Exam 1 practice questions

View Set

Collaborative-Health Promotion and Maintenance

View Set

Saunders Psychiatric Medications

View Set

Type of Insurance Policies (xcel solutions)

View Set

Molecular Symmetry and Molecular Orbital Theory

View Set

Toddler NCLEX, Toddler, Preschool-passp

View Set

The three main types of rocks and how they are formed

View Set