Skip to content

Instantly share code, notes, and snippets.

@kfranqueiro
Forked from rmurphey/screening.js
Created September 14, 2010 03:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kfranqueiro/578493 to your computer and use it in GitHub Desktop.
Save kfranqueiro/578493 to your computer and use it in GitHub Desktop.
// 1: how could you rewrite the following to make it shorter?
if (foo) {
bar.doSomething(el);
} else {
bar.doSomethingElse(el);
}
// 1A:
bar[foo ? 'doSomething' : 'doSomethingElse'](el);
// or if you want to go really nuts,
bar['doSomething' + (foo ? '' : 'Else')](el);
// not really sure the latter is worth it, but it IS shorter!
// 2: what is the faulty logic in the following code?
var foo = 'hello';
(function() {
var foo = foo || 'world';
console.log(foo);
})();
// 2A:
// global foo is immediately being obscured as soon as var foo occurs in the
// scope of the function, so 'world' will always be printed despite potential
// intentions otherwise. Here's a couple ways of rewriting the function:
// a. rename the inner variable to avoid the issue completely
(function() {
var myFoo = foo || 'world';
console.log(myFoo); // 'hello'
})();
// b. refer to the global variable directly via the window object
// (or dojo.global, etc.)
(function() {
var foo = window.foo || 'world';
console.log(foo); // 'hello'
})();
// 3: given the following code, how would you override the value of the bar
// property for the variable foo without affecting the value of the bar
// property for the variable bim? how would you affect the value of the bar
// property for both foo and bim? how would you add a method to foo and bim to
// console.log the value of each object's bar property? how would you tell if
// the object's bar property had been overridden for the particular object?
var Thinger = function() {
return this;
};
Thinger.prototype = {
bar : 'baz'
};
var foo = new Thinger(),
bim = new Thinger();
// 3A:
// affect only foo:
foo.bar = 'somethingElse';
// affect foo and bim (and every other instance):
Thinger.prototype.bar = 'someOtherThing';
// adding a method to log each object's bar property:
// Adding a method to the prototype would certainly be more efficient than
// adding a method to each instance:
Thinger.prototype.logBar = function() {
console.log(this.bar);
};
// Method telling whether or not a particular instance overrode bar:
Thinger.prototype.wasBarjacked = function() {
return this.hasOwnProperty('bar'); // true if instance's bar was overridden
}
// 4: given the following code, and assuming that each defined object has a
// 'destroy' method, how would you destroy all of the objects contained in the
// myObjects object?
var myObjects = {
thinger : new myApp.Thinger(),
gizmo : new myApp.Gizmo(),
widget : new myApp.Widget()
};
// 4A: I assume you want this iteratively, since one-by-one isn't interesting.
var k;
for (k in myObjects) {
if (myObjects.hasOwnProperty(k)) {
myObjects[k].destroy();
}
}
// Alternatively, I've seen things done in this style as well:
var k, empty = {};
for (k in myObjects) {
if (k in empty) {
continue; // skip anything found enumerable in the Object prototype
}
myObjects[k].destroy();
}
// This seems to be marginally faster, but is likely unnoticeable in small objects.
// 5: given the following array, create an array that contains the contents of
// each array item repeated three times, with a space between each item. so,
// for example, if an array item is 'foo' then the new array should contain an
// array item 'foo foo foo'. (you can assume the library of your choice is
// available)
var myArray = [ 'foo', 'bar', 'baz' ];
// 5A: I'll provide a few varieties here.
// First, an orthodox but completely unimaginative answer.
// Call this e.g. thriceArray(myArray);
function thriceArray(arr) {
var ret = [], i, len, value;
for (i = 0, len = arr.length; i < len; i++) {
value = arr[i];
ret[i] = value + ' ' + value + ' ' + value;
}
return ret;
}
// Second, a slightly less orthodox/performant but far more genericized version.
// This can be passed an array and an integer dictating how many times
// the value should be repeated in each value in the new array. So
// echoingArray(myArray, 3) would give you the result you're asking for.
function echoingArray(arr, num) {
var ret = [], i, j, len, value, pieces;
for (i = 0, len = arr.length; i < len; i++) {
value = arr[i];
pieces = [];
for (j = 0; j < num; j++) {
pieces[j] = value;
}
ret[i] = pieces.join(' ');
}
return ret;
}
// Third, the same as the second but assuming ES5 support:
function echoingArray(arr, num) {
return arr.map(function(value) {
var pieces = [], i;
for (i = 0; i < num; i++) {
pieces[i] = value;
}
return pieces.join(' ');
});
}
// This is actually faster than the second in Firefox.
// 6: how could you improve the following code?
$(document).ready(function() {
$('.foo #bar').css('color', 'red');
$('.foo #bar').css('border', '1px solid blue');
$('.foo #bar').text('new text!');
$('.foo #bar').click(function() {
$(this).attr('title', 'new title');
$(this).width('100px');
});
$('.foo #bar').click();
});
// 6A: I'm no jQuery veteran, but a few things stick out:
// (1) you could put all of these invocations into a single chain to avoid
// re-querying eeeevery siiingle tiiiiime.
// (2) #bar should only match a single element in the document since it's an id;
// using $('#bar') will thus perform better since it equates to
// document.getElementById('bar') instead of using QSA or otherwise.
// 7: what issues do you see with the following code? how would you fix it?
(function() {
var foo;
dojo.xhrGet({
url : 'foo.php',
load : function(resp) {
foo = resp.foo;
}
});
if (foo) {
// run this important code
}
})();
// 7A: This code naively expects dojo.xhrGet to perform synchronously.
// The first solution would simply be to perform the "important code" within
// the load callback. You could also run the "important code" in an additional
// callback added onto the deferred object returned by dojo.xhrGet, via
// .addCallback (Dojo < 1.5) or .then (preferred in Dojo >= 1.5).
// e.g.:
dojo.xhrGet({ /* ... */ }).then(function(resp) {
if (resp.foo) { /* ... */ }
});
// 8: how could you rewrite the following code to make it shorter?
(function(d, $){
$('li.foo a').attr('title', 'i am foo');
$('li.bar a').attr('title', 'i am bar');
$('li.baz a').attr('title', 'i am baz');
$('li.bop a').attr('title', 'i am bop');
})(dojo, dojo.query);
// 8A: Here's one way:
(function(d, $){
d.forEach(['foo', 'bar', 'baz', 'bop'], function(cls) {
$('li.' + cls + ' a').attr('title', 'i am ' + cls);
});
})(dojo, dojo.query);
// 9: how would you improve the following code?
for (i = 0; i <= 100; i++) {
$('#thinger').append('<p><span class="thinger">i am thinger ' + i + '</span></p>');
$('#gizmo').append('<p><span class="gizmo">i am gizmo ' + i + '</span></p>');
}
// 9A: I might be missing the point of this one entirely...
// The main thing I'd think of doing is crafting the entirety of each appended
// HTML string within a variable, then appending to the DOM in two big
// operations rather than 100 little ones, since DOM is notoriously the "weakest
// link" in browser performance.
// 10: a user enters their desired tip into a text box; the baseTotal, tax,
// and fee values are provided by the application. what are some potential
// issues with the following function for calculating the total?
function calculateTotal(baseTotal, tip, tax, fee) {
return baseTotal + tip + tax + fee;
}
// 10A: This is being dangerously naive about validity of user input.
// Results could vary wildly depending what the user inputs here, but you
// could easily end up with some kind of nonsense result.
// Here's an example of quickly running a simple sanity check along the way
// (assuming that all of the application inputs are guaranteed to be sound, we
// need only be concerned with the validity of the user input):
function calculateTotal(baseTotal, tip, tax, fee) {
var iTip = parseInt(tip, 10); // don't take any chances on a funky radix
if (iTip <= 0 || isNaN(iTip)) { // user input is non-positive or downright invalid/blank
alert('Trying to skip out on the tip?');
return false; // false returned on invalid input
}
return baseTotal + iTip + tax + fee;
}
// 11: given the following data structure, write code that returns an array
// containing the name of each item, followed by a comma-separated list of
// the item's extras, if it has any. e.g.
//
// [ "Salad (Chicken, Steak, Shrimp)", ... ]
//
// (you can assume the library of your choice is available)
var menuItems = [
{
id : 1,
name : 'Salad',
extras : [
'Chicken', 'Steak', 'Shrimp'
]
},
{
id : 2,
name : 'Potato',
extras : [
'Bacon', 'Sour Cream', 'Shrimp'
]
},
{
id : 3,
name : 'Sandwich',
extras : [
'Turkey', 'Bacon'
]
},
{
id : 4,
name : 'Bread'
}
];
// 10A: assuming ES5, if that's there I don't need libraries for Array.map
function menu2array(menu) {
return menu.map(function(item) {
return item.name + (item.extras ? ' (' + item.extras.join(', ') + ')' : '');
});
}
// BONUS: write code such that the following alerts "Hello World"
say('Hello')('World');
// B1A:
function say(something) {
return function(somethingElse) {
alert(something + ' ' + somethingElse);
};
}
// BONUS: what is the faulty logic in the following code? how would you fix it?
var date = new Date(),
day = date.getDate(),
month = date.getMonth(),
dates = [];
for (var i = 0; i <= 5; i++) {
dates.push(month + '/' + (day + i));
}
console.log('The next five days are ', dates.join(', '));
// B2A: There are a few faults here actually that I can see.
// (1) This assumes MM/DD format, which is only valid in certain locales
// (2) This completely ignores the possibility of "overflow" (e.g. what if
// day is 28?)
// (3) date.getMonth() is actually zero-based, so this will likely not give the
// results expected.
// Here's one attempt at resolving some of these issues...
var date = new Date(), i, dates = [];
for (i = 0; i <= 5; i++) {
//push date objects that are increasingly one day in the future
dates.push(new Date(date.getTime() + i * 86400000));
}
//now do whatever you want with the resulting date objects, e.g.
//dates[i].toLocaleString(), or perhaps something with dojo.date.locale.format
//(or do whatever inside the loop, then push the result)
/*
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment