intermediate javascript

79
JavaScript 200 Intermediate JavaScript by Milan Adamovsky http://milan.adamovsky.com http://www.hardcorejs.com

Upload: -milan-adamovsky-

Post on 20-May-2015

1.031 views

Category:

Technology


0 download

DESCRIPTION

These are slides I use in my Professional Intermediate JavaScript classes. Contact me to schedule training.

TRANSCRIPT

Page 1: Intermediate JavaScript

JavaScript 200Intermediate JavaScript

by Milan Adamovskyhttp://milan.adamovsky.com ◆ http://www.hardcorejs.com

Page 2: Intermediate JavaScript

Prerequisites

•Fundamentals of language

•Familiarity with syntax

•Distinction between DOM and JS

•Awareness of prototype and scope

•Basic understanding of this

Page 3: Intermediate JavaScript

Goals•Progressive complexity

•Eye on performance

•Familiarity with subtleties

•Explanation of some of the internals

•Awareness of new ways of doing things

Page 4: Intermediate JavaScript

Roadmap•How to better control our code’s flow

•How the code handles information

•How information is resolved

•How to practically apply advanced features

•Introduction to more advanced topics

Page 5: Intermediate JavaScript

Data Structures

Page 6: Intermediate JavaScript

Refresher Quiz•What is an identifier?

•What are valid characters in identifiers?

•What type system does the language use?

•What are the primitives?

•What primitives are mutable?

Page 7: Intermediate JavaScript

Immutability•Most primitives are immutable

•Type undefined is erroneously mutable

•Objects are mutable

•Literals are immutable

•Some array methods mutate, some don’t

Page 8: Intermediate JavaScript

Hoisting•Identifier is known to scope before

value

•Function names hoist after variables

•Value of variables never hoist

•Declaration of functions always hoist

•Reflect hoisting in coding style

Page 9: Intermediate JavaScript

Examplefunction myFunction() { if (!x) console.log('undefined') else console.log('x : ', x); var x = ""; function x() { console.log('inside x function'); }

}

myFunction();

x : function x() { console.log('inside x function'); }

Page 10: Intermediate JavaScript

Performance•Primitives are best

•Arrays are second best

•Objects are worst

•Keep nesting to a minimum

•Indexes better alternatives to nesting

Page 11: Intermediate JavaScript

Examplevar family = { father : { first : 'joe', last : 'doe' }, mother : { first : 'jane', last : 'doe' } };

var father = { first : 'joe', last : 'doe' }, mother = { first : 'jane', last : 'doe' };

Page 12: Intermediate JavaScript

Benchmark•http://jsperf.com/registry-design

•Strategic approach to data structures

•Different approach, different performance

•Shows nested objects are worst

•Suggests multiple objects best

Page 13: Intermediate JavaScript

Reminders•Use typeof to determine type of

variable

•Use instanceOf to determine class type

•Types via typeof are returned as strings

•Type of null is ‘object’

•Type of NaN is ‘number’

Page 14: Intermediate JavaScript

Conditionals

Page 15: Intermediate JavaScript

Refresher Quiz•What is logic flow?

•What different ways can we control it?

•What is a comparison operator?

•What is the triple equal operator?

•What does every condition resolve for?

Page 16: Intermediate JavaScript

Logic Flow

•if, if...else, if...else if...else

•Ternary operator (?:)

•Logical operators (||, &&, !)

•Switch statement

•Loops

Page 17: Intermediate JavaScript

Effective Conditions•Avoid unnecessary checks

•Order conditions from most to least likely

•Nest ifs to avoid redundant checks

•Optional braces for single statements

•Avoid function calls in conditions

Page 18: Intermediate JavaScript

Examplefunction multiply() { console.log('call to multiply'); return 100 * 100; } if (multiply() < 100) console.log('lt 100');else if (multiply() < 100 && multiply() === 1000) console.log('lt 100 and equal to 1000');else if (multiply() > 100 && multiply() < 100) console.log('gt 100 and lt 100');else if (multiply() > 100 || multiply() < 100) console.log('gt 100 or lt 100');else console.log('how did we get here?');

call to multiplycall to multiplycall to multiplycall to multiplycall to multiplygt 100 or lt 100

call to multiply

Page 19: Intermediate JavaScript

Examplefunction multiply() { console.log('call to multiply'); return 100 * 100; }

var result = multiply();

if (result < 100) if (result === 1000) console.log('lt 100 and equal to 1000'); else console.log('lt 100');else if (result > 100) console.log('gt 100');else console.log('how did we get here?');

call to multiplygt 100

call to multiply

Page 20: Intermediate JavaScript

Creative Uses•Use logical operators for defaults

values

•Use ternary operator for assignments

•Use ifs for logic flow

•Nest ternary operators

•Replace conditions with maps

Page 21: Intermediate JavaScript

Examplefunction namePerson(firstName, lastName) { firstName = firstName || "Unknown", lastName = lastName || "Doe"; console.log("Person's name is: ", firstName, lastName); }

namePerson();namePerson("Joe");namePerson("", "Doeson");namePerson("Bob", "Doeson");

Person's name is: Unknown DoePerson's name is: Joe DoePerson's name is: Unknown DoesonPerson's name is: Bob Doeson

Page 22: Intermediate JavaScript

Examplevar x = (firstCondition) ? (trueFirstCondition) ? firstConditionTrueValue : firstConditionFalseValue : falseFirstConditionValue;

var y;

if (firstCondition) if (trueFirstCondition) y = firstConditionTrueValue; else y = firstConditionFalseValue;else y = falseFirstConditionValue;

Page 23: Intermediate JavaScript

Objects

Page 24: Intermediate JavaScript

Object Literals

•Lightweight

•No prototype of its own

•No private variables

•Non-inheritable

•Faster than an instantiated object

Page 25: Intermediate JavaScript

Examplevar x = { first : "one", second : "two" };

x.prototype.test = "Test!";

TypeError: Cannot set property 'test' of undefined

Page 26: Intermediate JavaScript

ExampleObject.prototype.third = "three";

var x = { first : "one", second : "two" }, y = {};

console.log(x);console.log(y);

Object {first: "one", second: "two", third: "three"}Object {third: "three"}

Page 27: Intermediate JavaScript

ExampleObject.prototype.third = "three";

var x = { first : "one", second : "two" }, y = {};

console.log(delete x.third);console.log(x);

console.log(delete Object.prototype.third);console.log(x);

trueObject {first: "one", second: "two", third: "three"}trueObject {first: "one", second: "two"}

Page 28: Intermediate JavaScript

Instantiated Objects

•Use of new operator

•Comes with its own prototype

•Has a constructor

•Ideal for Object Oriented Programming

•Permits proper encapsulation

Page 29: Intermediate JavaScript

Examplefunction MyClass() { var myName = "Joe";

} MyClass.prototype.test = "Test";

var x = new MyClass(), y = {};

console.log(x);console.log(y);

MyClass {test: "Test"}Object {}

Page 30: Intermediate JavaScript

Exercisefunction MyClass() { var myName = "Joe";

}

Object.prototype.test = "Test 1"MyClass.prototype.test = "Test 2";

var x = new MyClass();

x.test = "Test 3";

console.log(x);

MyClass {test: "Test 3", test: "Test 2", test: "Test 1"}

Page 31: Intermediate JavaScript

Careful•Ensure parent object always exists

•Careful not to cause looping references

•Accidental array to object coercions

•Resist extending Object prototype

•IE errors on trailing commas in literals

Page 32: Intermediate JavaScript

Examplevar x = { y : null };

x.y = x;

Object {y: Object}

Page 33: Intermediate JavaScript

What can be done

•Dynamic keys introduced via [ ]

•Dot notation is optional

•Use of delete to remove keys

•Use of in to determine if key exists

•Enumerate keys using in

Page 34: Intermediate JavaScript

Examplevar x = { "name" : "Joe" }; console.log(x.name);console.log(x['name']);

var newKey = "arbitrary";

x[newKey] = "value";

x;

JoeJoeObject {name: "Joe", arbitrary: "value"}

Page 35: Intermediate JavaScript

Look ahead•ES5 offers Object.create()

•Upcoming property descriptors

•Getters and setters

•Proxy API in ES6

•ES5 gives access to keys via Object.keys()

Page 36: Intermediate JavaScript

Scope

Page 37: Intermediate JavaScript

Refresher

•Global and functional

•No block scope

•The let keyword is not part of ES5

•Skipping var globalizes identifier

•Scope chain

Page 38: Intermediate JavaScript

Scope Types•Lexical scope can be resolved lexically

•Dynamic scope doesn’t exist

•Lexical and global not mutually exclusive

•Name binding applies with call() and apply()

•Dynamics present with with() and eval()

Page 39: Intermediate JavaScript

Why to know•Understand how variables are

resolved

•Optimize code by reducing lookups

•Clarify understanding of closures

•Identify potential memory leaks

•Detect potential name resolution conflicts

Page 40: Intermediate JavaScript

Exercisefunction A(a) { function B(b) { function C(c) { console.log(a); } C(); } B(); }

var a = "Joe";A(a);

Joe

Page 41: Intermediate JavaScript

Functions

Page 42: Intermediate JavaScript

Review

•Declarations

•Expressions

•Constructor

•Anonymous functions

•Type of function

Page 43: Intermediate JavaScript

Nesting•Limit nesting to one level if

possible

•Each level introduces a link in scope chain

•Deteriorates performance

•Careful of inadvertent nestings

•Avoid wherever possible

Page 44: Intermediate JavaScript

Examplefunction A(a) { B(a); }

function B(a) { C(a); }

function C(a) { console.log(a); }

A("Joe");

output if any

Page 45: Intermediate JavaScript

Declarations•Best performance

•Always hoist name and definition

•Must be a source-element

•Converts to expression for non-sourced

•Using function statement

Page 46: Intermediate JavaScript

ExampleA();

function A() { console.log('A'); B(); if (!true) { function B() { console.log('B 2'); } } }

function B() { console.log('B 1'); }

AB 2

Page 47: Intermediate JavaScript

Expressions•Usually anonymous

•Variable is a reference to function

•Named expressions useful for tracing

•Name accessible within function only

•Using function operator

Page 48: Intermediate JavaScript

Examplevar referenceAx = function Ax() { console.log(Ax); }; referenceAx();Ax();

function Ax() { console.log(Ax); }

ReferenceError: Ax is not defined

Page 49: Intermediate JavaScript

Arguments

•Always passed by value

•There is no by reference

•Always optional

•Always accessible via arguments

•Array-like object but not an array

Page 50: Intermediate JavaScript

Examplefunction prove(objectliteral) { objectliteral.key = true; objectliteral = undefined; }

var objectliteral = {key: false};

prove(objectliteral);

objectliteral.key;

true

Page 51: Intermediate JavaScript

Examplefunction prove(objectliteral) { var myaddress = objectliteral; // let's copy the value of the argument that supposedly // contains the address.

objectliteral.key = true; objectliteral = null;

myaddress.key = 1; // now we should be modifying the key of the objectliteral's address // which the objectliteral variable no longer has since we wiped it. // Since we now have the address, we can reference the key of that // object.}

var objectliteral = {key: false};

prove(objectliteral);

objectliteral.key;

1

Page 52: Intermediate JavaScript

Memoization•Reduces need for redundant

calculations

•Cache derived values where possible

•Maintain easy-to-access registries

•Use getters and setters for control

•Weigh use of closures versus conditions

Page 53: Intermediate JavaScript

Examplefunction resolveNumber() { var result = 100 * 100; resolveNumber = function () { return result; }; return resolveNumber(result); }

console.log(resolveNumber);console.log(resolveNumber());console.log(resolveNumber);

function resolveNumber() { var result = 100 * 100; resolveNumber = function () { return result; }; return resolveNumber(result); }10000function () { return result; }

Page 54: Intermediate JavaScript

Prototype

Page 55: Intermediate JavaScript

Concept•Defines an object

•Inheritable to inherited objects

•Propagates to all new and existing objects

•Has a constructor property

•Good way to extend objects

Page 56: Intermediate JavaScript

Prototype chain•Resolve availability of method or

property

•Similar to scope chain

•Each link traversal incurs cost

•Reduce inheritance for better performance

•Final link is null

Page 57: Intermediate JavaScript

Bad practice•Do not extend native object

prototypes

•Poor use of inheritance

•Looping without use of hasOwnProperty

•Carelessly extending an object

•Don’t forget to reset constructor

Page 58: Intermediate JavaScript

Closures

Page 59: Intermediate JavaScript

Concept•Shared variables between multiple

scopes

•Extends variable life beyond a scope’s end

•Inner scope can access outer scope

•Outer scope cannot access inner scope

•Locks up memory until freed

Page 60: Intermediate JavaScript

Examplefunction A(x) { var b = 1; return function B() { debugger; return x; }; }

var c1 = A(1);c1;

function B() { debugger; return x; }

Page 61: Intermediate JavaScript

Expressions

Page 62: Intermediate JavaScript

Overview•Executed left-to-right

•Comma-separate multiple expressions

•Returns value of last expression

•Expressions always return a value

• Two types of expressions

Page 63: Intermediate JavaScript

Regex

Page 64: Intermediate JavaScript

When to use•Match patterns in text

•Can be used with split()

•Also available with replace()

•Weigh performance versus complexity

•Time is of the essence

Page 65: Intermediate JavaScript

Advanced features

•Flags

•Captures

•Lookahead

•Negated lookahead

•Negated character set

Page 66: Intermediate JavaScript

Examplevar pattern = ".{1}\s*[a-z]+";

var re = new RegExp("[0-9]" + pattern + "$", "gi");

var regex = /\d{2}\s*[A-Z]/gi;

console.log("33v 45d".match(regex));

console.log("4@jK".match(re));

console.log(/(Joe\ +)(?=Doe)/.test("Joe Doe"));

console.log(/(Joe)\ +(?=Doe)/.test("Joe Bob"));

["33v", "45d"]["4@jK"]truefalse

Page 67: Intermediate JavaScript

Common use cases•Determine valid phone number

•Determine valid e-mail address

•Extract specific values from a string

•Parse CSV data

•Check for existence of content

Page 68: Intermediate JavaScript

Patterns

Page 69: Intermediate JavaScript

Good to know•Understand how DOM and JS

interact

•Memory leaks between DOM and JS

•DOM transactions are costly

•Patterns in JS can help with DOM

•Patterns for DOM better use jQuery

Page 70: Intermediate JavaScript

Observer pattern•Used to decouple cause and effect

•Trigger event unaware of effect

•Event handlers respond to event

•Similar to publish / subscribe pattern

•Many frameworks use it already

Page 71: Intermediate JavaScript

MVC pattern•Model, View, Controller

•Separation of concerns

•Comes in different flavors

•Ideal candidate to mix with Observer

•Promotes use of templates

Page 72: Intermediate JavaScript

Effective Coding

Page 73: Intermediate JavaScript

Coding Style•Standardization improves quality

•Uses Java’s naming convention de facto

•Camel casing of identifiers

•Uppercase first letter to suggest a Class

•Alphabetize function definitions

Page 74: Intermediate JavaScript

Resources

Page 75: Intermediate JavaScript

Garbage collection•Uses a mark and sweep strategy

•Assign a null value to help clean up

•Use of delete to help clean up

•Consistency helps with performance

•Proprietary GarbageCollect() not so good

Page 76: Intermediate JavaScript

Debugging

Page 77: Intermediate JavaScript

Use of features

•Breakpoints

•Call stack

•The debugger statement

•Acceptable uses of alert()

•Acceptable uses of console API

Page 78: Intermediate JavaScript

Console API•Bad idea to override console

•Use of console.log() to navigate objects

•Use of different console methods

•Using console.warn() shows up in-code

•Easy to shim

Page 79: Intermediate JavaScript

Connect•Thank you for your time

•Connect with me on LinkedIn

•Join the Hardcore JavaScript community

•Read my blog

•Contact me via e-mail