<repo_name>kmillns/js-interview<file_sep>/questions/simple_click_handler.js
<a href="#">Show it.</a>

<div style="display: none;">
	<span>Hidden stuff.</span>	
</div>


// write a simple click handler to show the hidden div<file_sep>/solutions/scope_and_hoisting.js
// What gets logged to the console?

var foo = 'hello';

(function() {
  var foo = foo || 'world';
  console.log(foo);
})();

// Answer: 'world'

// This is a bog simple case of variable hoisting and scope precendence
// It's much clearer once you break it down into what the interpreter is doing

// Step one: variables are hoisted to the top of their scope.
var foo = 'hello';

(function() {
  var foo;
  foo = foo || 'world';
  console.log(foo);
})();

// Step two, unassigned variables are undefined 
var foo = 'hello';

(function() {
  var foo;
  foo = undefined || 'world';
  console.log(foo);
})();

// Step three and undefined is falsey, therefore assign 'world' to foo
var foo = 'hello';

(function() {
  var foo;
  foo = false || 'world';
  console.log(foo);
})();

// For bonus points:
// What's logged to the console here

var foo = 'hello';

(function() {
  var foo = foo || 'world';
  console.log(foo);
})();

console.log(foo);

// Answer: 
// 'world'
// 'hello'

// Because the inner function scoped foo doesn't affect the outer variable
// just overwrites it locally.
<file_sep>/questions/functional_programming.js
// Write code such that the following alerts "Hello World"
say('Hello')('World');<file_sep>/solutions/preventDefault_return_false.js
<div>
	<a href="/doStuff">foo</a>
</div>


// what's the difference between these three click handlers?

// This version will prevent the default action (following the link)
// but will also stop propogation (events bound up the DOM won't recieve it),
// and stop immediate propogation (subsequent events on this element won't
// receive it, either)
$('a').on('click', function (event) {
	$(this).doStuff();

	return false;
});

// Both of these two examples only prevent default, which allows for
// propogation normally.
// The difference is subtle, and relates to what happens in a failure case.
// In the first example, if doStuff() fails, you still click through to the
// underlying link action.
// In the second, if doStuff() fails, your link is dead, and does nothing.

// Thus, the second example (preventDefault *last* in the event handler) is
// the preferable option for progressive enhancement purposes.

$('a').on('click', function (event) {
	$(this).doStuff();

	event.preventDefault();
});


$('a').on('click', function (event) {
	event.preventDefault();

	$(this).doStuff();
});
<file_sep>/solutions/prototypes.js
// 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();


// 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?

// What we're looking for here is if you understand the property lookup chain.
// Local properties are tried first and don't affect other objects' properties.

foo.bar = 'override';

bim.bar === 'baz'; // true


// how would you affect the value of
// the bar property for both foo and bim?
// Note: this only affects the value if it *hasn't* been set locally

// This time we're asking for the other side of things.
// Altering a prototype alters the objects that have been created with that
// prototype *even after they've been created*.

Thinger.prototype.bar = 'woo';

bim.bar === 'woo'; // true
foo.bar === 'woo'; // false (foo is using its local value)
foo.bar === 'override'; // true

// how would you add a method to
// foo and bim to console.log the value of each object's bar property?

// Here we're testing adding objects to the prototype after the objects
// were created.
// Also, we're testing if you understand the scope of 'this' inside prototype
// properties points to the instance of the object.

Thinger.prototype.logger = function () {
	console.log(this.bar);
}

foo.logger(); // logs 'override'
bar.logger(); // logs 'woo'


// how
// would you tell if the object's bar property had been overridden for the
// particular object?

// Testing if you understand 'hasOwnProperty'

foo.hasOwnProperty('bar'); // true
bim.hasOwnProperty('bar'); // false

// BONUS: When would you use 'hasOwnProperty' in practice?

// Crockford-ian Answer:
// As a filter when enumerating over an object's properties with
// for ( in ) {} loops to defend against taking prototype properties

Array.prototype.badIdea = function () {
	console.log('oh god why are you modifying globals?!');
};

var test = [1, 2, 3];

var i;

for (i in test) {
	console.log(i);
}

// Oh no you broke it.

for (i in test) {
	if (test.hasOwnProperty(i)) {
		console.log(i);
	}
}

// jQuery answer:
// Test if an object is a plain object based on the presence of a constructor
// or prototype

core_hasOwn = Object.prototype.hasOwnProperty

isPlainObject: function( obj ) {
		// Must be an Object.
		// Because of IE, we also have to check the presence of the constructor property.
		// Make sure that DOM nodes and window objects don't pass through, as well
		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
			return false;
		}

		try {
			// Not own constructor property must be Object
			if ( obj.constructor &&
				!core_hasOwn.call(obj, "constructor") &&
				!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
				return false;
			}
		} catch ( e ) {
			// IE8,9 Will throw exceptions on certain host objects #9897
			return false;
		}

		// Own properties are enumerated firstly, so to speed up,
		// if last one is own, then all properties are own.

		var key;
		for ( key in obj ) {}

		return key === undefined || core_hasOwn.call( obj, key );
	}
<file_sep>/questions/module_pattern.js
// How would you update this function to make the last two lines true

var first = '1';
var second = '2';
var name = 'foo';

var foo = (function () {

})();

foo.one === '1foo';
foo.two === '2foo';<file_sep>/solutions/jQuery_refactoring.js
// 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();
});

// First thing I see is selector caching:

// 6: how could you improve the following code?
$(document).ready(function () {
	var $fooBar = $('.foo #bar');
	$fooBar.css('color', 'red');
	$fooBar.css('border', '1px solid blue');
	$fooBar.text('new text!');
	$fooBar.click(function () {
		$(this).attr('title', 'new title');
		$(this).width('100px');
	});

	$fooBar.click();
});

// Don't forget to cache $(this)

$(document).ready(function () {
	var $fooBar = $('.foo #bar');
	$fooBar.css('color', 'red');
	$fooBar.css('border', '1px solid blue');
	$fooBar.text('new text!');
	$fooBar.click(function () {
		var $this = $(this);
		$this.attr('title', 'new title');
		$this.width('100px');
	});

	$fooBar.click();
});

// The $ prefix is a psuedo-Hungarian notation convention that says that the
// object is a jQuery selector result.  Not necessary, but idiomatic
// and a standard for us.

// Second thing is that we can chain the calls

$(document).ready(function () {
	var $fooBar = $('.foo #bar');
	$fooBar
		.css('color', 'red')
		.css('border', '1px solid blue')
		.text('new text!')
		.click(function () {
			var $this = $(this);
			$this
				.attr('title', 'new title')
				.width('100px');
		})
		.click();
});

// and yes, the chaining eliminates the need for selector caching in this case.
// The selector caching is still a good idea, and readability is preferred over
// clever chaining.

// Finally, you can condense the multiple CSS calls:

$(document).ready(function () {
	var $fooBar = $('.foo #bar');
	$fooBar
		.css({
			color: 'red',
			border: '1px solid blue'
		})
		.text('new text!')
		.click(function () {
			var $this = $(this);
			$this
				.attr('title', 'new title')
				.width('100px');
		})
		.click();
});

// Bonus points:

// An id selector should very very rarely depend on being inside a class,
// since a given id should be extremely specific.

var $fooBar = $('.foo #bar');

// becomes

var $bar = $('#bar');


// The CSS manipulation in JS creates mainentance and reuse problems

$fooBar
	.css({
		color: 'red',
		border: '1px solid blue'
	})

// becomes

$fooBar
	.addClass('funkyColor')

// with some CSS

.funkyColor {
	color: red;
	border: 1px solid blue;
}

// Triple testability bonus points:

// Extract the click handler into a named function:

$(document).ready(function () {
	var titleIt = function () {
		var $this = $(this);
		$this
			.attr('title', 'new title')
			.width('100px');
	};

	var $fooBar = $('#bar');
	$fooBar
		.addClass('funkyColor')
		.text('new text!')
		.click(titleIt)
		.click();
});

// Expose the whole thing outside the ready function as a testable object

window.funkifier = {
	titler: function () {
		var $this = $(this);
		$this
			.attr('title', 'new title')
			.width('100px');
	},

	makeFunky: function (elementToFunkify) {
		var $target = $(elementToFunkify);
		$target
			.addClass('funkyColor')
			.text('new text!')
			.click(funkifier.titler)
			.click();
	}
};

$(document).on('ready', function () {
	window.funkifier.makeFunky('#bar');
});

// Now we can test 'titler' and 'makeFunky' individually, rather than just
// testing their side effects

// Alternatively you could create a Funkifier object to be constructed
// with the properties you want to expose.

window.Funkifier = function (elementToFunkify) {
	var self = this;

	self.titler = function () {
		var $this = $(this);
		$this
			.attr('title', 'new title')
			.width('100px');
	};

	self.makeFunky = function () {
		var $target = $(elementToFunkify);
		$target
			.addClass('funkyColor')
			.text('new text!')
			.click(self.titler)
			.click();
	};

	return {
		titler: self.titler,
		makeFunky: self.makeFunky
	};
};

$(document).on('ready', function () {
	var funkifier = new Funkifier('#bar');

	funkifier.makeFunky();
});

<file_sep>/questions/ternary_and_bracket_property_access.js
// 1: how could you rewrite the following to make it shorter?
if (foo) {
  bar.doSomething(el);
} else {
  bar.doSomethingElse(el);
}<file_sep>/questions/scope_and_hoisting.js
// What gets logged to the console?

var foo = 'hello';

(function() {
  var foo = foo || 'world';
  console.log(foo);
})();