Last active
January 23, 2019 21:36
-
-
Save jeremiahlangner/0d77f9aa69b265d52ab327e5772d403e to your computer and use it in GitHub Desktop.
Sticky JS issues, often used in code interviews. Use, memorize, steal from at your leisure.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* Instructions: | |
* | |
* Fix closure error in the following for loop so that, when clicked the button | |
* logs it's own number. | |
* | |
*/ | |
(function() { | |
for(var i = 1; i <= 10; i++) { | |
var input = document.createElement('button'); | |
input.innerHTML = 'button ' + i; | |
input.onclick = function(e) { | |
console.log(i); | |
} | |
document.querySelector('body').appendChild(input); | |
} | |
})(); | |
/** | |
* | |
* Solutions: Each of these produces the desired result, though the first | |
* actually solves the "closure error." | |
* | |
*/ | |
/* Using Closure */ | |
(function() { | |
for(var i = 1; i <= 10; i++) { | |
(function(i) { | |
var input = document.createElement('button'); | |
input.innerHTML = 'button ' + i; | |
input.onclick = function(e) { | |
console.log(i); | |
} | |
document.querySelector('body').appendChild(input); | |
})(i); | |
} | |
})(); | |
/* Using ES6 limited variable scope */ | |
(function() { | |
for(let i = 0; i < 10; i++) { | |
let input = document.createElement('button'); | |
input.innerHTML = `button ${i}`; | |
input.onclick = function(e) { | |
console.log(i); | |
} | |
document.querySelector('body').appendChild(input); | |
} | |
})(); | |
/* Calling external function with own closure; technically a "closure-based" solution */ | |
(function() { | |
function createElement(i) { | |
var input = document.createElement('button'); | |
input.innerHTML = 'button ' + i; | |
input.onclick = function(e) { | |
console.log(i); | |
} | |
document.querySelector('body').appendChild(input); | |
} | |
for(var i = 0; i < 10; i++) { | |
createElement(i); | |
} | |
})(); | |
/* Spawning a function for each step. */ | |
(function() { | |
for(var i = 0; i < 10; i++) { | |
function doThis(i) { | |
let input = document.createElement('button'); | |
input.innerHTML = 'button ' + i; | |
input.onclick = function(e) { | |
console.log(i); | |
} | |
document.querySelector('body').appendChild(input); | |
} | |
doThis(i); | |
} | |
})(); | |
/* Using forEach */ | |
(function() { | |
for(var i = 0; i < 10; i++) { | |
var input = document.createElement('button'); | |
input.innerHTML = 'button ' + i; | |
document.querySelector('body').appendChild(input); | |
} | |
let buttons = document.querySelectorAll('button'); | |
[].forEach.call(buttons, function(button, i) { | |
button.onclick = function(e) { | |
console.log(i); | |
}; | |
}); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* Instructions: | |
* | |
* Merge two sorted arrays in as efficient manner as possible. arr1, and arr2. | |
* | |
*/ | |
function mergeTwo(arr1, arr2) { | |
let merged = []; | |
let index1 = 0; | |
let index2 = 0; | |
let current = 0; | |
while (current < (arr1.length + arr2.length)) { | |
let isArr1Depleted = index1 >= arr1.length; | |
let isArr2Depleted = index2 >= arr2.length; | |
if (!isArr1Depleted && (isArr2Depleted || (arr1[index1] < arr2[index2]))) { | |
merged[current] = arr1[index1]; | |
index1++; | |
} else { | |
merged[current] = arr2[index2]; | |
index2++; | |
} | |
current++; | |
} | |
return merged; | |
} | |
let result = mergeTwo(arr1, arr2); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<body> | |
<button id="add">+</button> | |
<span id="result">0</span> | |
<button id="subtract">-</button> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.3.3/rxjs.umd.min.js"></script> | |
<script> | |
/** | |
* | |
* Observables: | |
* | |
* Create a basic observable that increments or decrements a value based on | |
* user input. | |
* | |
*/ | |
(function() { | |
const Rx = window['rxjs']; | |
console.log(window); | |
const addButton = document.getElementById('add'); | |
const subtractButton = document.getElementById('subtract'); | |
const resultDisplay = document.getElementById('result'); | |
const addEvent = Rx.fromEvent(addButton, 'click'); | |
const subtractEvent = Rx.fromEvent(subtractButton, 'click'); | |
const add = addEvent.pipe(Rx.operators.map(e => e = 1)); | |
const subtract = subtractEvent.pipe(Rx.operators.map(e => e = -1)); | |
const source = Rx.merge(add, subtract); | |
var subscribe = source.subscribe(val => resultDisplay.innerHTML = parseInt(resultDisplay.innerHTML) + val); | |
})(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* | |
* Promises: | |
* | |
* Instructions: | |
* | |
* The promise doesn't seem to return anything. Find the missing syntax | |
* and fix anything that's missing. | |
* | |
*/ | |
(function() { | |
var promise = new Promise((resolve, reject) => { | |
var err; | |
if(err) { | |
reject(err); | |
} | |
var p = 'foo'; | |
resolve(p); | |
}); | |
})(); | |
/** | |
* | |
* Solutions: | |
* | |
* Clearly the promise is never used. | |
* | |
*/ | |
(function() { | |
var promise = new Promise((resolve, reject) => { | |
var err; | |
if(err) { | |
reject(err); | |
} | |
var p = 'foo'; | |
resolve(p); | |
}); | |
promise.then(function(p) { | |
console.log(p); | |
}); | |
})(); | |
/** | |
* | |
* Promise Libraries: | |
* | |
* Instructions: | |
* | |
* Execute a callback from a Promise for the requested option. | |
* | |
*/ | |
(function() { | |
var promiseLib = { | |
resolvePromise: function() { | |
return new Promise((resolve, reject) => { | |
var err; | |
if(err) { | |
reject('there was an error'); | |
} | |
function getRandomValue() { | |
var i = Math.round(Math.random()); | |
if(i) { | |
resolve('two'); | |
} else { | |
resolve('three'); | |
} | |
} | |
getRandomValue(); | |
}) | |
}, | |
on: function(req, cb) { | |
this.resolvePromise().then(function(res) { | |
if(req == res) { | |
cb(res); | |
} | |
}); | |
} | |
}; | |
promiseLib.on('two', function(res) { | |
console.log('response was ' + res); | |
}); | |
promiseLib.on('three', function(res) { | |
console.log('response was ' + res); | |
}); | |
})(); | |
/** | |
* | |
* Instructions: Create an externally cancellable Promise. | |
* | |
*/ | |
(function() { | |
function makePromise() { | |
let promise = new Promise((resolve, reject) => { | |
setTimeout(() => { | |
resolve('There was a problem with the cancellation.'); | |
}, 1000); | |
}); | |
let cancel = new Promise((resolve, reject) => { | |
console.log(`I resolve on receiving input/an event from somewhere else.`); | |
window.addEventListener('PromiseCancellation', () => { | |
resolve('canceled'); | |
}); | |
}); | |
Promise.race([promise, cancel]).then((result) => { | |
console.log(result); | |
}); | |
} | |
function cancel() { | |
let cancel = new Event('PromiseCancellation'); | |
window.dispatchEvent(cancel); | |
} | |
makePromise(); | |
cancel(); | |
})(); | |
/* Using reject() instead of race() */ | |
(function() { | |
function makePromise(cb) { | |
let promise = new Promise((resolve, reject) => { | |
let err; | |
if(err) { | |
reject('There was an error.'); | |
} | |
window.addEventListener('PromiseCancellation', () => { | |
reject('Received a request to cancel the promise.'); | |
}); | |
setTimeout(() => { | |
resolve('There was a problem with the cancellation.'); | |
}, 1000); | |
}); | |
promise.then((res) => { | |
cb(); | |
}); | |
} | |
function cancel() { | |
let cancel = new Event('PromiseCancellation'); | |
window.dispatchEvent(cancel); | |
} | |
makePromise(); | |
cancel(); | |
})(); | |
/** | |
* | |
* Async/Await: | |
* | |
* Create a promise function that follows an async/await try/catch pattern. | |
* | |
*/ | |
(function() { | |
function makePromise() { | |
return new Promise((resolve, reject) => { | |
let err; | |
if(err) { | |
reject(err); | |
} | |
resolve('This promise has been fulfilled.') | |
}) | |
} | |
async function getPromiseResult() { | |
try { | |
const result = await makePromise(); | |
console.log(result); | |
} | |
catch (err) { | |
console.log(err); | |
} | |
} | |
getPromiseResult(); | |
})(); | |
/* Async promise fulfillment in a loop. Resolve using promise.all. */ | |
(function() { | |
function getAThing(thing) { | |
return new Promise((resolve, reject) => { | |
let thing = "something wonderful"; | |
resolve(thing); | |
}); | |
} | |
function retrieveThings(thingsArr) { | |
return new Promise((resolve, reject) => { | |
let promiseArr = []; | |
thingsArr.forEach(thing => { | |
let promise = getAThing(thing); | |
promiseArr.push(promise); | |
}); | |
Promise.all(promiseArr).then((data) => { | |
resolve(data); | |
}); | |
}); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment