Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Alex Reichert edited this page Jul 25, 2016 · 1 revision

Misconceptions:

  • Javascript is an interpreted language (not really?)
  • Hoisting (variables, declared functions are not really hoisted)

Is Javascript an interpreted language?

Not really.

  • Javascript is compiled. A bug on line 10 can prevent lines 1-9 from running. This wouldn't happen in a truly interpreted language.
  • After Java is compiled into byte-code, it needs to run through the Java Virtual Machine (JVM) to be interpreted
  • The JS engine does something similar
  • The JS compiler is one of the most sophisticated compilers in existence (one reason is due to JS being dynamically typed, "type inferencing")

Scope

"Where to look for things"

Javascript has function scope only?

/*
 this is treated as two different statements
 var foo is handled at compilation:
 compiler looks for formal declarations ("var")
 compiler asks scope manager (global scope): do you have anything for "foo" identifier?
 scope manager says "no", so registers it in memory

 foo = "bar" is handled at execution time
*/
var foo = "bar";

/*
 same thing happens, but in new scope
*/
function bar() {
  var foo = "baz"; // "shadowing" means we can never access global "foo" in this scope
}

/*
 formal declaration is the same for parameter "foo"
 JS will not allow multiple parameters of the same name

 "bam" doesn't get handled during compile time, it gets handled at execution time
 because var bam; could appear later in the code, so the compiler leaves it alone
*/
function baz(foo) {
  // hey scope of baz, I have an LHS reference of foo, do you have it in memory?
  // yes! from the parameter
  foo = "bam"; 
  
  // hey scope of baz, have you heard of bam?
  // nope. let's go up one level (in this case to global scope) and ask
  // global scope will throw an error in strict mode,
  // but in lazy mode it will create a reference in the global scope, not local
  bam = "yay"; // not a formal declaration
}

"Hoisting":

var foo = "test";

function bar() {
  foo = "huh?"; // not assigned to global scope foo!
  
  var foo = "in bar";
}

// is the same as:
function bar() {
  var foo; // because this is done at compilation, not really "hoisted"

  foo = "huh?";
  foo = "in bar";
}

Undeclared and undefined are not synonyms! Undefined values have been formally declared.

Always write in strict mode!

Always prefer named function expressions to anonymous function expressions!

  • Better for using function within function (recursion)
  • Better for debugging, looking through stack traces
  • Makes code more readable, self-documenting

This is one of the downsides of arrow functions, since these are always anonymous.

Why use a linter? Only for code style, not for bugs. Correct code is handled by the compiler, and should be handled by tests.

Just don't use eval (duh)... mainly for performance reasons. If the JS engine finds eval anywhere in a file, it disables a ton of optimizations.

IIFE can be written like so:

void function IIFE() {
  // don't worry about polluting global scope!
}();

Good practice:

(function IIFE(global, $) {
  // cleans up global/jQuery calls/assignments
})(window, jQuery);

Function hoisting is great for readability:

// Look at the top to see what gets executed first!
init();

// Function declarations all get hoisted
function init() {
  foo();
  bar();
}

function foo() {

}

function bar() {

}

Two aspects of module pattern:

  • Outer enclosing function that runs at least once
  • Function should return an object that contains at least one inner function (using closure)
  • Expose a minimal public API (hide implementation details)

What is a closure?

  • When a function remembers the outer lexical variables it has access to
  • When you take that function and put it in a different scope
  • When a function remembers its lexical scope, while executing in a different scope

How long does its scope stay around?

  • (I forget)

What happens when you use the new keyword?

  • Brand new empty object
  • Gets linked to another object
  • Newly created and linked object gets passed in as the this keyword
  • Returns its this (unless function explicitly returns an object)

Prototypal Inheritance

  • A constructor makes an object linked to its own prototype
  • Don't be misled by the constructor keyword!
  • New instances don't receive copies from their "constructor", so properties can be added retroactively but updating the prototype

What is a constructor call?

  • The new keyword put in front of any function

What is Prototype and where does it come from?

  • It's a reference linkage between two objects, which occurs when the object is created

How does Prototype affect the behavior of an object?

  • Whenever we ask for a property on an object, we find it by walking up the prototype chain

How do we find out where an object's Prototype points to?

  • Object.getPrototypeOf, __proto__, constructor.prototype

Javascript OLOO Design

Delegation/"Objects Linked to Other Objects"

Better than referring to it as "inheritance"

Use Object.create instead!

var Widget = {
	setDimensions: function(width,height) {
		this.width = width || 50;
		this.height = height || 50;
		this.$elem = null;
	},
	buildDOMElement: function($where) {
		if (this.$elem) {
			this.$elem.css({
				width: this.width + "px",
				height: this.height + "px"
			}).appendTo($where);
		}
	}
};

var Button = Object.assign(Object.create(Widget), {
	configure: function(width, height, label) {
		// delegated call
		this.setDimensions(width, height);
		this.label = label || "Default";

		this.$elem = $("<button>").text(this.label);
	},
	activate: function($where) {
		// delegated call
		this.buildDOMElement($where);
		this.$elem.click(this.onClick.bind(this));
	},
	onClick: function(evt) {
		console.log("Button '" + this.label + "' clicked!");
	}
});

How is Javascript's Prototype chain not like traditional/classical inheritance?

  • It's a link up instead of a copy down

What does Prototype delegation mean and how does it describe object linking in JS?

  • Intentionally separate objects, so we can combine them as needed (virtual composition)

What are the benefits of the "behavior delegation" design pattern?

  • Simpler code, easier to test
  • Simpler design pattern

What are the tradeoffs of using Prototype?

  • Anything on the prototype is public (this is why modules are good)
Clone this wiki locally