Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

1394 lines (1116 sloc) 47.534 kb
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>The Art of JavaScript : Level Up Your Skills in 60 Minutes</title>
<meta name="description" content="A presentation on JavaScript fundamentals for ColdFusion developers.">
<meta name="author" content="Ryan Anklam">
<meta name="viewport" content="width=1024, user-scalable=no">
<!-- Core and extension CSS files -->
<link href="google-code-prettify/prettify.css" type="text/css" rel="stylesheet" />
<link rel="stylesheet" href="core/deck.core.css">
<link rel="stylesheet" href="extensions/goto/deck.goto.css">
<link rel="stylesheet" href="extensions/menu/deck.menu.css">
<link rel="stylesheet" href="extensions/navigation/deck.navigation.css">
<link rel="stylesheet" href="extensions/status/deck.status.css">
<link rel="stylesheet" href="extensions/hash/deck.hash.css">
<link rel="stylesheet" href="extensions/codemirror/deck.codemirror.css">
<!-- Theme CSS files (menu swaps these out)
<link rel="stylesheet" id="style-theme-link" href="themes/style/web-2.0.css">
-->
<link rel="stylesheet" id="transition-theme-link" href="themes/transition/horizontal-slide.css">
<!-- Custom CSS just for this page -->
<link rel="stylesheet" href="introduction.css">
<link rel="stylesheet" href="extensions/codemirror/themes/default.css">
</head>
<body class="deck-container" onload="prettyPrint()">
<!--
Title
-->
<div class="slide" id="title-slide">
<ul>
<li>Water</li>
<li>Turn off all chrome extentions</li>
<li>Console Font Bigger</li>
<li>Close Tabs</li>
<li>Close IM's</li>
<li>Close Console & reload preso</li>
</ul>
</div>
<div class="slide" id="introslide">
<h1>The Art of JavaScript: Level Up Your Skills In 60 Minutes</h1>
</div>
<!--
About me
-->
<div class="slide" id="about-me">
<h2>Obligitory About me</h2>
<h3>Contact</h3>
<ul style="list-style:none">
<li>ryan.anklam@gmail.com</li>
<li>@bittersweetryan (Twitter, GitHub)</li>
<li><a href="http://blog.bittersweetryan.com" target="_blank">blog.bittersweetryan.com</a></li>
</ul>
<h3>Experience</h3>
<ul>
<li>Technical Solutions Architect at IDL Solutions <a href="http://www.idl.com" target="_blank">http://www.idl.com</a>.</li>
<li>Web Developer since 1997</li>
<li>I ♥ Open Source
<ul>
<li>
<strong>Author</strong>: ColdFusion Koans, GitHub News Filter (Chrome Extension), Envelope.js
</li>
<li>
<strong>Contributor</strong>: JavaScript Koans, MXUnit, FW/1
</li>
</ul>
</li>
<li>Known To Make Obscure Simpsons Refernces. D'oh!</li>
</ul>
</div>
<!--
Cover
-->
<div class="slide" id="what-well-cover">
<h2>What we'll cover</h2>
<p>We will cover A LOT of ground! Please feel free to stop me in the halls, email me, or tweet at me to talk about any part of this presentation!</p>
<ul>
<li class="slide">
<h3>Basics</h3>
</li>
<li class="slide">
<h3>Objects</h3>
</li>
<li class="slide">
<h3>Functions</h3>
</li>
<li class="slide">
<h3>Inheritance</h3>
</li>
<li class="slide">
<h3>This</h3>
</li>
<li class="slide">
<h3>Design Patterns</h3>
</li>
</ul>
</div>
<div class="slide" id="basics">
<h1>Let's Start With Some Basics</h1>
</div>
<!--
Variables
-->
<div class="slide">
<h1>Variables</h1>
</div>
<div class="slide">
<h2>Variables</h2>
<h4>There are 6 data types in JavaScript</h4>
<ul>
<li class="slide"><code class="prettyPrint">string</code></li>
<li class="slide"><code class="prettyPrint">number</code></li>
<li class="slide"><code class="prettyPrint">object</code> (functions and arrays are technically objects)</li>
<li class="slide"><code class="prettyPrint">boolean</code></li>
<li class="slide"><code class="prettyPrint">undefined</code> (dont initialize values to undefined, its semantically incorrect)</li>
<li class="slide"><code class="prettyPrint">null</code> (use null to initialize empty values)</li>
</ul>
</div>
<div class="slide">
<h2>Variables</h2>
<p>JavaScript variables are only scoped within functions, and they are poorly scoped by default. Any variable that is declared in a function without the var keyword goes into the global scope. In a browser the global scope is the window object.</p>
<pre><code class="prettyprint">function doSomething(){
myVar = &quot;foo&quot;; //this goes into the global scope
var myOtherVar = &quot;bar&quot;; //this goes into the function scope
}
console.log( myVar ); //foo
console.log( myOtherVar ); //error
</code></pre>
<input type="button" data-run="scoping" value="Run">
</div>
<div class="slide">
<h2>D'oh!</h2>
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">function doSometing(){
for( i = 0; i < 10; i++ ){
doMore();
console.log( i );
}
}
function doMore(){
for( i = 0; i < 10; i++ ){
//do some stuff
}
};
doSometing();</textarea>
</div>
<div class="slide">
<h2>Thats better!</h2>
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">function doSometing(){
for( var i = 0; i < 10; i++ ){
doMore();
console.log( i );
}
}
function doMore(){
for( var i = 0; i < 10; i++ ){
//do some stuff
}
};
doSometing();</textarea>
</div>
<!--
Numbers
-->
<div class="slide">
<h2>Numbers</h2>
<p class="slide">All numbers in JavaScript are 64 bit floating point numbers.</p>
<div class="slide">
<p>Floating point arithmatic sometimes give strange results (<a href="http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html">http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html</a>).</p>
<div> <!-- constrain the textarea -->
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var result = 0.06 + 0.01;
console.log( "0.06 + 0.01 = " + result );</textarea>
</div>
<br>
<p class="slide">JavaScript has a BigNum library which will improve the accuracy of floating point expressions at <a href="https://github.com/jtobey/javascript-bignum" target="_blank">https://github.com/jtobey/javascript-bignum</a></p>
</div>
<div class="slide">
<p>Use the <code class="prettyprint">toFixed()</code> method to round a number to a specified number of decimal places.</p>
<div>
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">console.log( 3.14159.toFixed( 2 ) ); </textarea>
</div>
</div>
</div>
<div class="slide">
<h2>Numbers</h2>
<p><code class="prettyprint">NaN</code>, is a special value in JavaScript. You'll get NaN in situations like trying to do math on a variable that is <code class="prettyprint">undefined</code> or trying to perform multiplication, division, or subtraction on a string.</p>
<ul>
<li class="slide"><code class="prettyprint">NaN is False</code></li>
<li class="slide"><code class="prettyprint">NaN !== NaN (NaN is not even != NaN)</code></li>
<li class="slide"><code class="prettyprint">typeof NaN</code> is number.</li>
<li class="slide">Use <code class="prettyprint">isNaN()</code> to test for NaN</li>
</ul>
</div>
<!--
Arrays
-->
<div class="slide" id="arrays">
<h1>Arrays</h1>
</div>
<div class="slide">
<h2>Arrays</h2>
<P>Arrays can be created two ways:</P>
<pre><code class="prettyprint">var myArray = new Array( 'item1', 'item2', myobj, [] );</code></pre>
<p>AND</p>
<pre><code class="prettyprint">var myArray = [ "item1", "item2", myObj, [] ]; //prefered</code></pre>
<p>In order to create multi-dimensional arrays in JavaScript you nest arrays:</p>
<pre><code class="prettyprint">myArray[ 0 ] = [ "nested one", "nested two" ];
myArray[ 0 ][ 1 ]; //nested two</code></pre>
</div>
<div class="slide">
<h2>Arrays</h2>
<p>Arrays are objects so they have methods.</p>
<div><pre><code class="prettyprint">myArray.length //mutable in JS, set length to resize arary
myArray.push( item ) //append item to the end of the array
myArray.pop() //removes the last element of the array and returns it
myArray.concat( anotherArray ) //adds two arrays together, returns a new array. myArray unchanged!
myArray.join( &quot;,&quot; ) //combines elements into string, separated by argument</code></pre></div>
</div>
<div class="slide">
<h2>Arrays</h2>
<p>More methods:</p>
<div><pre><code class="prettyprint">myArray.sort( function( a, b ) {
if( a < b )
return -1;
if( a > b)
return 1;
//elements are equal
return 0;
})//sorts an array
myArray.slice( 1, 2 ) //returns 2 items from the array starting at position 1
myArray.shift() //removes the first element of the array and returns it</code></pre></div>
</div>
<div class="slide">
<h2>Arrays</h2>
<p>Use push & pop together to create a stack (LIFO)</p>
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myStack = [ 'Aaron', 'Drew', 'Tom', 'Peyton' ];
myStack.push( 'Eli' );
console.log( myStack );
console.log( myStack.pop() );
console.log( myStack )
console.log( myStack.pop() );
console.log( myStack )</textarea>
</div>
<div class="slide">
<h2>Arrays</h2>
<p>Use push & shift together to create a queue (FIFO)</p>
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myQueue = [ 'Aaron', 'Drew', 'Tom', 'Peyton' ];
myQueue.push( 'Eli' );
console.log( myQueue );
console.log( myQueue.shift() );
console.log( myQueue );
console.log( myQueue.shift() );
console.log( myQueue );</textarea>
</div>
<div class="slide">
<h2>Arrays</h2>
<p>Use use <code class="prettyprint">slice()</code> to make a one level deep copy of an Array.</p>
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myArray = [ 'Aaron', 'Drew', 'Tom', 'Peyton' ];
var myArray2 = myArray; //holds a reference to myArray
var myArray3 = myArray.slice(); //is truly a new array
myArray2[ 2 ] = 'Cam'; //changes myArray
myArray3[ 1 ] = 'Phillip'
console.log( myArray );
console.log( myArray2 );
console.log( myArray3 );</textarea>
</div>
<!--
Operators
-->
<div class="slide" id="operators">
<h1>Operators</h1>
</div>
<div class="slide">
<h2>Comparisons</h2>
<p>In JavaScript there are TWO sets of comparison operators;</p>
<ul>
<li class="slide">Type coercion operators: <code class="prettyprint">==</code> and <code class="prettyprint">!=</code></li>
<li class="slide">Non-type coercion operators (AKA exactly equal): <code class="prettyprint">===</code> and <code class="prettyprint">!==</code></li>
</ul>
</div>
<div class="slide">
<h2>Comparisons</h2>
<p>What exactly is type coersion?</p>
<div>
<textarea id="code1" name="code" class="code" mode="javascript" style="display: none;" runnable="true">console.log( "1" == 1 );
console.log( "1" === 1 );
console.log( [7] == 7 );
console.log( [7] === 7 );
console.log( false == '' );
console.log( false === '' );</textarea>
</div><br>
<p class="slide"><strong>
Always use === when comparing a variable <code class="prettyprint">0</code>, <code class="prettyprint">undefined</code>, booleans, <code class="prettyprint">null</code>, and empty strings "".</strong>
</p>
</div>
<div class="slide">
<h2>Truthy / Falsy Values</h2>
<p>The following values evaluate to <code class="prettyprint">false</code>, since some of them not primitive boolean datatypes they are said to be "falsy".</p>
<h3>Falsy Values</h3>
<ul>
<li>
<code class="prettyprint">false</code>
</li>
<li>
<code class="prettyprint">0</code>
</li>
<li>
""
</li>
<li>
<code class="prettyprint">undefined</code>
</li>
<li>
<code class="prettyprint">NaN</code>
</li>
<li>
<code class="prettyprint">null</code>
</li>
</ul>
<p><strong>Anything that is not falsy is truthy in JavaScript.</strong></p>
</div>
<!--
<div class="slide">
<h2>Comparisons</h2>
<p>If I'm using === and I know "<code class="prettyprint">1</code>" is a numeric value how do I get "<code class="prettyprint">1</code>" to equal <code class="prettyprint">1</code>?</p>
<ol>
<li class="slide">
Use the Number object: <code class="prettyprint">var num = Number("1").</code>
</li>
<li class="slide">
<p>
Use the parseInt function: <code class="prettyprint">var num = parseInt("01",10)</code>.</p>
<p>The second param is the radix. If it is omitted some browsers will treat numbers starting with 0 as an octal, and some a decimal. This is why its extremely important to always pass the radix parameter.</p>
</li>
<li class="slide">
If you are sure that the value you want to convert is an integer, you can use the "+" to convert a string to a number: <code class="prettyprint">var num = +&quot;3&quot;</code>.
</li>
</ol>
</div>
-->
<div class="slide" id="logical">
<h1>Logical Operators</h1>
</div>
<div class="slide">
<h2>Logical Operators</h2>
<h3>JavaScript OR Operator <code class="prettyprint">||</code></h3>
<p>The || operator returns the value of the first expression if it's true otherwise returns the value of the second expression.
<textarea id="code3" name="code" class="code" mode="javascript" style="display: none;" runnable="true">
console.log( null || "hello" );
console.log( "world" || "foo" );</textarea>
</div>
<div class="slide">
<div id="andor3">
<h2>Logical Operators</h2>
<p>The || operator can be used to set default values.</p>
<pre><code class="prettyprint">var myFunc = function( arg ){
var myVal = document.getElementById( arg ) ||
document.createElement( &quot;div&quot; ); //defaultValue
console.log( myVal );
};
myFunc( );
myFunc( &quot;andor3&quot; );</code></pre>
<input type="button" data-run="andor3" value="Run">
</div>
</div>
<div class="slide">
<h2>Logical</h2>
<h3>JavaScript AND Operator <code class="prettyprint">&&</code></h3>
<p>The <code class="prettyprint">&&</code> returns the value of the first expression if it is false, otherwise it returns the value of the second.</p>
<textarea id="code5" name="code" class="code" mode="javascript" style="display: none;" runnable="true">console.log( 1 - 1 && "Foo" );
console.log( 1 + 1 && "Bar" );</textarea>
</div>
<!--
<div class="slide">
<h2>Logical</h2>
<h3>Ternary</h3>
<p>The ternary operator is a terse way to do a simple if/else statement.</p>
<pre><code class="prettyprint">( conditional ) ? trueStatement : falseStatement ;</code></pre>
<textarea id="code5" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myVar = 10;
var myValue = ( myVar < 10 ) ? 'less than ten' :
'greater than or equal to ten';
console.log( myValue );</textarea>
</div>
-->
<!--
Objects
-->
<div class="slide" id="objects">
<h1>Objects</h1>
</div>
<div class="slide">
<h2>Objects</h2>
<p>Objects in JavaScript can be thought of as a set of key-value pairs.</p>
<pre><code class="prettyprint">myObject = { }; //empty object
myObject2 = {
foo : &quot;Foo&quot;,
bar : &quot;Bar&quot;,
anotherObject : {
baz : &quot;Baz&quot;,
pez : &quot;Pez&quot;
}
}; //this is called an object literal pattern</code></pre>
</div>
<div class="slide">
<h2>Objects</h2>
<p>You can access an object's properties with "dot" notation or with associative array notation</p>
<textarea id="code66" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myObject = {
foo : 'Foo'
};
myObject[ 'foo bar' ] = 'foo bar'; //non standard property names
console.log( myObject.foo );
console.log( myObject[ 'foo' ] );
console.log( myObject ['foo ' + 'bar' ] );</textarea>
</div>
<!--
<div class="slide">
<h2>Objects</h2>
<p>When accessing properties from other properties in an object, use the <code class="prettyprint">this</code> keyword.</p>
<textarea id="code7" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myObj = {
firstName : 'Homer',
sayHello : function(){
//omitting the this keyword below would generate an error
console.log( 'Hello, ' + this.firstName );
}
};
myObj.sayHello();</textarea>
</div>
-->
<!--
<div class="slide">
<h2>Objects</h2>
<p>To check if a property exists in an object use the <code class="prettyprint">hasOwnProperty()</code> method or the <code class="prettyprint">in</code> operator. <code class="prettyprint">hasOwnProperty</code> will only search the current object for a property whereas <code class="prettyprint">in</code> will search all the way up the prototype chain.</p>
<h3>JavaScript</h3>
<textarea id="code66" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myObject = {foo : 'Foo'};
myObject.__proto__ = { baz : "Baz" }; //we'll talk about this later
console.log( 'baz' in myObject );
console.log( myObject.hasOwnProperty( 'baz' ) );</textarea>
</div>
-->
<!--
Functions
-->
<div class="slide" id="functions">
<h1>Functions</h1>
</div>
<!--
<div class="slide">
<h2>Functions</h2>
<p>JavaScript functions are the beating heart of a JavaScript application and are one of the most powerful features of the language.</p>
<ul>
<li class="slide">All functions return something! If there is no <code class="prettyprint">return</code> statement a function will return the keyword <code class="prettyprint">undefined</code>.</li>
<li class="slide">Functions can have properties just like objects.</li>
</ul>
</div>
-->
<div class="slide" id="function3">
<h2>Creating Functions</h2>
<h3>Function Statement</h3>
<pre><code class="prettyprint">function myFunc( args ) {
...
};
</code></pre>
<h3>Function Expression</h3>
<p>Function expressions don't need to be named, these are called anonymous functions.</p>
<pre><code class="prettyprint">var myFunc = function( args ){
...
};
</code></pre>
</div>
<div class="slide">
<h2>Hoisting</h2>
<p>There is one fundamental difference between function expressions and statements: hoisting. Hoisting is when the JavaScript parser takes a function and variable declarations and moves them to the top of the current scope.</p>
</div>
<div class="slide">
<h2>Function Declaration Before Hoisting</h2>
<pre><code class="prettyprint">function hoistingExample(){
var firstVar;
firstVar = &quot;&quot;;
var secondVar = &quot;&quot;;
secondFunction( firstVar + secondVar );
firstFunction(); //throws an error
var firstFunction = function(){
//do something
};
function secondFunction(){
// do another thing
}
}</code></pre>
</div>
<div class="slide">
<h2>Function Declaration After Hoisting</h2>
<pre><code class="prettyprint">function hoistingExample(){
//the function statement has been brought to the top of the scope
function secondFunction(){
// do another thing
}
//declared the variables
var firstVar;
var secondVar;
var firstFun;
//instantiate the variables where they are in the code
firstVar = &quot;&quot;;
secondVar = &quot;&quot;;
secondFunction( firstVar + secondVar );
firstFunction();
firstFunction = function(){
//do something
}
}</code></pre>
</div>
<div class="slide">
<h2>Function Arguments</h2>
<p>Arguments in JavaScript are stored in an array-like object. The "arguments" object has a length property but none of the other array methods.</p>
<pre><code class="prettyprint">var myFunc = function(){
console.log( arguments );
};
myFunc( &quot;Hello&quot;, &quot;World&quot;, function(){} );</code></pre>
<input type="button" data-run="args" value="Run">
</div>
<div class="slide">
<h2>Function Arguments</h2>
<p>Since JavaScript is a type-less language its always a good idea to check the type of arguments.</p>
<p>To do this we are provided with the <code class="prettyprint">typeof</code> operator</p>
<div class="slide">
<textarea id="code10" name="code" class="code" mode="javascript" style="display: none;" runnable="true">console.log("Type of string: " + typeof "hello");
console.log( "Type of number: " + typeof 1234 );
console.log( "Type of object literal: " + typeof {} );
console.log( "Type of array: " + typeof [] ); //be carefull!
console.log( "Type of function: " + typeof function(){} );
console.log( "Type of function: " + typeof undefinedVar );</textarea>
</div>
<br>
<div class="slide">
<p>To check if a variable is defined or not you can use the <code class="prettyprint">typeof</code> operator on it.</p>
<p>Doing <code class="prettyprint">if( undefinedVar === 'undefined')</code> will throw an error.</p>
</div>
</div>
<!--
<div class="slide">
<h2>Function Arguments</h2>
<p>Hit the brakes!</p>
<div class="slide" id="checktype">
<pre><code class="prettyprint">console.log( typeof [] ); //object ?!?</code></pre>
</div>
<p class="slide">We have to work a little harder to check for an array</p>
<div class="slide">
<pre><code class="prettyprint">//borrowed from Douglas Crockford&#39;s &quot;JavaScript: The Good Parts&quot;
var is_array = function ( value ) {
return Object.prototype.toString.apply( value ) === &#39;[object Array]&#39;;
};</code></pre>
</div>
</div>
-->
<!--
<div class="slide">
<h2>Function Arguments</h2>
<p>All arguments JavaScript are passed <strong>by value</strong>, even though they act like they are being passed by reference.</p>
<textarea id="code2" name="code" class="code" mode="javascript" style="display: none;" runnable="true">function createCar(){
var myCar = { make : "Ford", model : "Fusion" };
changeCar( myCar );
//if mycar was passed by ref it would now be a Honda!
console.log(myCar);
}
function changeCar( theObj ){
theObj.make = "Chevy";
theObj.model = "Traverse";
theObj = {}; //this breaks the link between the value passed in and its reference
theObj.make = "Honda";
console.log( theObj );
}
createCar();</textarea>
</div>
<div class="slide">
<h2>Function Arguments</h2>
<div>
<p>A variable that holds an object is a pointer to the memory location of that object. When the argument is passed a copy is made of that pointer. When a new object is created the pointer now points to a different memory location.</p>
<img src="assets/by_value.png">
</div>
</div>
-->
<div class="slide">
<h2>Lexical Scoping</h2>
<p>Functions can be nested inside of other functions. Each nested function has access to the scope of all its parents. This is called lexical scoping. </p>
<!-- may have issues -->
<textarea id="code8" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var lexical = function(){
var outerVar = 'outer';
return function(){
var innerVar = "inner"; //outer function does not have access
console.log( outerVar );
return function(){
console.log( innerVar, outerVar );
}();
}();
};
lexical();</textarea>
</div>
<div class="slide">
<h2>Closures</h2>
<ul>
<li class="slide">Closures are created when a reference exists to a variable inside a function after that function has been invoked.</li>
<li class="slide">The execution context of that variables scope is saved and "wrapped" around that variable.</li>
<li class="slide">This effectively saves the "state" of that variables entire scope at the time the function is run.</li>
</ul>
</div>
<div class="slide">
<h2>Contrived Closure Example</h2>
<pre><code class="prettyprint">var timesCalled = function(){
var total = 0;
return function(){
total++;
console.log( total );
};
};
var callTimer = timesCalled(); //this call right here creates the closure
callTimer();</code></pre>
<input type="button" data-run="closure" value="Run">
</div>
<div class="slide">
<h2>Constructor Functions</h2>
<p>JavaScript has a special type of function called a <code class="prettyprint">Constructor</code> function.</p>
<ul>
<li class="slide">By convention the first letter of a constructor should be a capital letter.</li>
<li class="slide">Never use a constructor function without first using the <code class="prettyprint">new</code> keyword!</li>
<li class="slide">Using the new keyword will create a new scope for the function.</li>
<li class="slide">Using the new keyword will also create the inheritance tree. Without new a function will only inherit from the Function Constructor.</li>
</ul>
</div>
<div class="slide">
<h2>Constructor Functions</h2>
<textarea id="code11" name="code" class="code" mode="javascript" style="display: none;" runnable="true">//create a new constuctor function called Robot
var Robot = function( robotName ){
this.robotName = robotName;
};
//add a new property to the prototype (more on this soon)
Robot.prototype.walk = function(){
console.log( "Go " + this.robotName + " go!" );
};
//create a new instance of the robot using the new keyword
var robot = new Robot( "Ferbbot" );
//now we can tell the robot to walk
robot.walk();
var anotherRobot = Robot( "Phineasbot" ); //we just created a global!!
console.log( window.robotName ); //note that robotName is now a property of window
//anotherRobot.walk(); //doesn't exist</textarea>
</div>
<div class="slide">
<h2>Constructor Functions</h2>
<p>Create a new variable for our constructor function. Make sure the name starts with a capital letter!</p>
<pre><code class="prettyprint">var Robot = function( robotName ){
this.robotName = robotName;
};
</code></pre>
</div>
<div class="slide">
<h2>Constructor Functions</h2>
<p>Now add a new property to the prototype of the constructor.</p>
<p>This is initialized with the prototype chain when the <code class="prettyprint">new</code> keyword is used.</p>
<pre><code class="prettyprint">Robot.prototype.walk = function(){
console.log( "Go " + this.robotName + " go!" );
};</code></pre>
</div>
<div class="slide">
<h2>Constructor Functions</h2>
<p>Correct.</p>
<pre><code class="prettyprint">var robot = new Robot( "Ferbbot" );</code></pre>
<p>Incorrect, not using the keyword does not create a scope or a prototype chain.</p>
<pre><code class="prettyprint">var anotherRobot = Robot( "Phineasbot" );</code></pre>
</div>
<div class="slide">
<h2>Constructor Functions</h2>
<p>Without the <code class="prettyprint">new</code> keyword when the constructor is called <code clss="prettyprint">this</code> is equal to the global object.</p>
<pre><code class="prettyprint">var Robot = function( robotName ){
this.robotName = robotName; //this actually equals the window object in a browser
};
</code></pre>
</div>
<!--
This
-->
<div class="slide" id="this">
<h1>This</h1>
</div>
<div class="slide">
<h2>This</h2>
<p>The <code class="prettyprint">this</code> keyword one of JavaScript's most mis-understood keywords.</p>
<pre><code class="prettyprint">var myObj = {
myFunc : function(){
console.log( this );
}
};
var myFunc = function(){
console.log( this );
};
myObj.myFunc();
myFunc();</code></pre>
<input type="button" data-run="this1" value="Run">
</div>
<div class="slide">
<h2>This</h2>
<p>What happened in the function call? Why did this point to window and not the function?</p>
<p class="slide">In order to explain we must understand what "this" means in JavaScript. This refers to the <strong>current execution context.</strong></p>
<p class="slide">When we called the myFunc function from within the object, the object was the current execution context.</p>
<p class="slide">When we called myFunc() from the root of the script tag, the window object was the current execution context</p>
</div>
<div class="slide">
<h2>call() and apply()</h2>
<p>The <code class="prettyprint">call(this,arg1,arg2,arg3,...)</code> and <code class="prettyprint">apply(this,[args])</code> functions allow you to pass the value of <code class="prettyprint">this</code> as the first parameter.</p>
<p>The difference is that the call function takes in any number of arguments whereas the apply function takes an array of arguments as its second argument.</p>
<textarea id="code14" name="code" class="code" mode="javascript" style="display: none;" runnable="true">function whoAmI(){
console.log( "I am: " + this );
console.log( arguments );
}
whoAmI.call( "Ryan", "Hello World", undefined, {}, [] );
whoAmI.apply( "Scott", [ "Hello World", undefined, {}, [] ] );</textarea>
</div>
<div class="slide">
<h2>This</h2>
<p>Lets take a look at "this" when using a constructor function to create a new instance.</p>
<pre><code class="prettyprint">function Person( name ){
this.name = name;
console.log( this );
console.log( this.name );
}
var person = new Person( &quot;Bart&quot; );</code></pre>
<input type="button" data-run="this2" value="Run">
</div>
<div class="slide">
<h2>This In Object Literals</h2>
<p>In an object literal <code class="prettyprint">this</code> refers to the current object</p>
<textarea id="code16" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var myObj = {
firstName : "Homer",
sayHello : function(){
//omitting this would cause an error
console.log( "Hello, " + this.firstName );
}
};
myObj.sayHello();</textarea>
</div>
<div class="slide">
<h2>This In Object Literals</h2>
<p>Be careful when using <code class="prettyprint">this</code> in nested functions!</p>
<pre><code class="prettyprint">var myObj = {
firstName : &quot;Homer&quot;,
sayHello : function(){
//look what happens when this is used inside a nested function
return function(){
console.log( &quot;Hello, &quot; + this.firstName );
console.log( this );
};
}
};
myObj.sayHello();</code></pre>
<input type="button" data-run="this3" value="Run"><br><br>
<p class="slide">In nested functions <code class="prettyprint">this</code> refers back to global namespace!</p>
</div>
<!--
<div class="slide">
<h2>This and jQuery</h2>
<p>jQuery likes to normalize <code class="prettyprint">this</code>, which can cause issues if you expect <code class="prettyprint">this</code> to refer to the current object.</p>
<pre><code class="prettyprint">var obj = {
init : function(){
$( &#39;#thisButton&#39; ).on( &#39;click&#39;, function(){
console.log( this );
} );
}
};
obj.init();</code></pre>
<input type="button" id="thisButton" value="Run">
</div>
<div class="slide">
<h2>This and jQuery</h2>
<p>Luckily there is an easy fix that a lot of library authors have chosen to use.</p>
<pre><code class="prettyprint">var obj = {
init : function(){
var self = this; //create a ref to the current &quot;this&quot; scope
$( &quot;#this4&quot; ).on( &#39;click&#39;,function(){
console.log( self );
} );
}
};
obj.init();</code></pre>
<input type="button" id="thisButton1" value="Run">
</div>
-->
<div class="slide">
<h2>This</h2>
<p>For a much more comprehensive look at "this" and "function invocation" read:
<p class="slide">Yehuda Kat's blog post: <a href="http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/" target="_blank">http://yehudakatz.com/2011/08/11/understanding-javascript-function-invocation-and-this/</a></p>
<p class="slide">Scope In JavaScript: <a href="http://www.digital-web.com/articles/scope_in_javascript/">http://www.digital-web.com/articles/scope_in_javascript/</a></p>
</div>
<!--
Inheritence
-->
<div class="slide" id="inheritance">
<h1>Inheritance</h1>
</div>
<div class="slide">
<h2>Inheritance</h2>
<p>JavaScript uses a prototype-based inheritance model.</p>
<pre><code class="prettyprint">var Car = function(){ };
//add properties to Car&#39;s Prototype
Car.prototype = {
wheels : 4, doors : 4, manufacturer : &quot;&quot;
};
var Fusion = function(){ };
//set the Fusion&#39;s prototype to a new instance of car
Fusion.prototype = new Car();
Fusion.prototype.constructor = Fusion; //reset the Fusion&#39;s constructor
var fusion = new Fusion();
console.log( fusion );</code></pre>
<input type="button" data-run="inheritance1" value="Run">
</div>
<div class="slide">
<h2>Inheritance</h2>
<p>First we create a new constuctor function.</p>
<pre><code class="prettyprint">var Car = function(){ };
//add properties to Car&#39;s Prototype
Car.prototype = {
wheels : 4, doors : 4, manufacturer : &quot;&quot;
};
</code></pre>
</div>
<div class="slide">
<h2>Inheritance</h2>
<p>Then we create a new, more specialized constructor function, setting its prototype to a new instance of our Car constructor.</p>
<pre><code class="prettyprint">var Fusion = function(){ };
Fusion.prototype = new Car();
</code></pre>
<p>
Notice that we use <code class="prettyprint">Fusion.prototype = new Car()</code> and not:
<pre><code class="prettyprint">var Fusion = function(){
this.prototype = new Car();
};</code></pre>
</p>
<p>Setting <code class="prettyprint">this.prototype</code> will just add a new property to each <strong>instance</strong> of Fusion.</p>
</div>
<div class="slide">
<h2>Inheritance</h2>
<p>Overriding an objects prototype also overrides a property called <code class="prettyprint">prototype.constructor</code>.</p>
<p>Its important to reset this property, otherwise the <code class="prettyprint">instanceof</code> operator won't work properly.</p>
<p><code class="prettyprint">instanceof</code> is used weather if a variables is an intance of a particular prototype.</p>
<pre><code class="prettyprint">Fusion.prototype.constructor = Fusion;
var fusion = new Fusion();
fusion instanceof Fusion //true</code></pre>
</div>
<div class="slide">
<h2>What is a "Prototype"</h2>
<p class="slide">A prototype is just an object. Functions and objects have a hidden link to an object that is it's prototype.</p>
<p class="slide">In some browsers the prototype object is exposed as <code class="prettyprint">__proto__ </code>.</p>
<p class="slide">When a property is called the property is searched for on the object, then the objects prototype, then the prototype's prototype, etc</p>
<p class="slide">JavaScript stops looking up the chain when it reaches Object.prototype</p>
</div>
<!--
<div class="slide">
<h2>Prototype's Members</h2>
<p>Adding to an object's prototype link is "live". This means that properties added to a prototype are immediately accessable by all existing instances.</p>
<textarea id="code21" name="code" class="code" mode="javascript" style="display: none;" runnable="true">function RealObject( name ){
this.name = name
};
var instanceOfRealObject = new RealObject( "Ryan" );
var anotherOfRealObject = new RealObject( "Scott" );
//we can add to a prototype at any time
RealObject.prototype.iRule = function(){
return this.name + " Rules.";
};
console.log( instanceOfRealObject.iRule() );
console.log( anotherOfRealObject.iRule() );</textarea>
</div>
-->
<!--
<div class="slide">
<h2>Prototype on native Objects</h2>
<p>You can also change the prototypes of the native objects like Object or Array</p>
<p>Since there is no "deep copy" method available to arrays, lets add one.</p>
<p><strong>Just because you can, doesn't mean you should!</strong></p>
<textarea id="code22" name="code" class="code" mode="javascript" style="display: none;" runnable="true">Array.prototype.deepCopy = function(){
return this.slice(); //this refers to the array object.
};
var myArray = [ "Apple", "Peach", "Pear" ];
var copiedArray = myArray.deepCopy();
copiedArray[ 0 ] = "Banana";
console.log( copiedArray );
console.log( myArray );</textarea>
</div>
-->
<!--
Design Patterns
-->
<div class="slide" id="designPatterns">
<h1>Common JavaScript-Centric Design Patterns</h1>
</div>
<div class="slide">
<h2>Namespacing</h2>
<p>Namespacing is a way of not polluting a namespace for smaller sized applications.</p>
<p>Its a quick and easy way to clean up a lot of code in the $(document).ready() callback.</p>
<pre><code class="prettyprint">$( function(){
$( &#39;#getUsers&#39; ).on( &#39;click&#39;,function(){
//get users
} );
var addUser = function(){
//add
}
var userDiv = $( &quot;#userDiv&quot; );
} );</code></pre>
</div>
<div class="slide">
<h2>Namespacing</h2>
<pre><code class="prettyprint">var userApp = {
$userDiv : null,
$getUsers : null,
init : function(){
this.$userDiv = $( &quot;#userDiv&quot; );
this.$getUsers = $( &quot;#getUsers&quot; );
this.$getUsers.on( &#39;click&#39;,$.proxy( this,this.getUsers );
},
getUsers : function(){
//get users
this.addUser( user );
},
addUser = function( user ){
this.userDiv.append( user );
}
};
$( function(){
userApp.init();
} );</code></pre>
</div>
<div class="slide">
<h2>Module Pattern</h2>
<p>The module pattern can be used to "hide" variables and functions.</p>
<textarea id="code23" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var publicFunctions = ( function(){
var firstName = 'Aaron', //private
lastName = 'Rodgers'; //private
var getFullName = function(){ //private
return firstName + ' ' + lastName;
};
var publicFn = {
sayHello : function(){
console.log( "Hello, " + getFullName() );
}
};
return publicFn; //only what is returned is public
} () ); /*remember the closure slide? This function is immediately
invoked creating a closure */
publicFunctions.sayHello();</textarea>
</div>
<div class="slide">
<h2>Options</h2>
<p>The options pattern is a way to specify options and default values using a single argument.</P>
<pre><code class="prettyprint">$.fn.myPlugin = function( options ){
var defaults = { color: &quot;blue&quot;, height: &quot;200px&quot; };
//remember to check the type of the argument!
if( typeof options === &#39;object&#39; ){
options = $.extend( defaults, options );
} else {
options = defaults;
}
console.log( options );
};
$( document ).myPlugin( { color:&#39;black&#39;, height: &#39;500px&#39; } );
$( document ).myPlugin();</code></pre>
​<input type="button" data-run="optionsPattern" value="Run">
</div>
<div class="slide">
<h2>Pub-Sub (AKA Observer)</h2>
<p>The pub-sub pattern specifies that there are "publishers" that publish events, and "subscribers" that can subscribe to those events.</p>
<img src="assets/pub_sub.png">
</div>
<!--
<div class="slide">
<h2>Pub-Sub (AKA Observer)</h2>
<p>This pattern you probably already use every day.</p>
<pre><code class="prettyprint">​&lt;a href=&quot;#&quot; id=&quot;clickMe&quot;&gt;Observe Me&lt;/a&gt;</code></pre>
<pre><code class="prettyprint">​​//clickme&#39;s click event is the &quot;publisher&quot;
//the anonymous function parameters are the subscribers
$(&quot;#clickMe&quot;).on(&#39;click&#39;,function(){
console.log(&quot;First Observable of click&quot;);
});
$(&quot;#clickMe&quot;).on(&#39;click&#39;,function(){
console.log(&quot;Second Observable of click&quot;);
});</code></pre>
</div>
-->
<div class="slide">
<h2>Pub-Sub (AKA Observer)</h2>
<pre><code class="prettyprint">​var contacts = {
collection : [ &#39;Aaron&#39;, &#39;Drew&#39;, &#39;Tom&#39; ],
update : function(){
this.collection[ 0 ] = &#39;Arian&#39;;
this.collection[ 1 ] = &#39;Adrian&#39;;
this.collection[ 2 ] = &#39;Ray&#39;;
$( this ).trigger( &#39;change&#39; );
}
}; //publisher
$( contacts ).on( &#39;change&#39;,function(){
//subscribers
var contactSelect = $( &#39;select[ name=&quot;contact&quot; ]&#39; );
contactSelect.find( &#39;option&#39; ).remove();
for(var i = 0; i &lt; contacts.collection.length; i++){
contactSelect.append( &#39;&lt;option value=&quot;&quot;&gt;&#39; + contacts.collection[ i] + &#39;&lt;/option&gt;&#39; );
}
});
contacts.update();</code></pre>
<select name="contact">
<option value="">Aaron</option>
<option value="">Drew</option>
<option value="">Tom</option>
</select>
<select name="contact">
<option value="">Aaron</option>
<option value="">Drew</option>
<option value="">Tom</option>
</select>
<input type="button" data-run="pubSub" value="Run">
</div>
<!--
<div class="slide">
<h2>Prototype</h2>
<p>Don't confuse the prototype pattern with prototypical inheritance we talked about earlier!</p>
<p>The prototype pattern is a pattern where an object is used for the prototype of another object.</p>
<textarea id="code25" name="code" class="code" mode="javascript" style="display: none;" runnable="true">var motorcycle = {
wheels : 2,
engine : "250cc",
go : function(){ console.log( "Rumble rumble rumble." ); }
};
var sportbike = {
engine: "1000cc",
go : function(){ console.log( "Waaaaaaaaa" ); },
fairings : "blue"
};
for(var attr in motorcycle){
if( !sportbike[ attr ] ){
sportbike[ attr ] = motorcycle[ attr ];
}
}
console.log( sportbike );
sportbike.go();
motorcycle.go();</textarea>
</div>
-->
<div class="slide">
<h2>Design Patterns</h2>
<p>Be sure to check out Addi Osmani's "Essential JavaScript Design Patterns" open source book at: <a href="https://github.com/addyosmani/essential-js-design-patterns" target="_blank">https://github.com/addyosmani/essential-js-design-patterns</a></p>
</div>
<!--
Resources
-->
<div class="slide" id="resources">
<h1>Resources</h1>
</div>
<div class="slide">
<h2>Resources</h2>
<p>You can get really good at JavaScript without spending a single penny!</p>
<ul>
<li>JavaScript Enlightenment (now open source!) <a href="http://javascriptenlightenment.com/" target="_blank">http://javascriptenlightenment.com/</a></li>
<li>Marijn Haverbeke's Eloquent JavaScript <a href="http://eloquentjavascript.net/contents.html" target="_blank">http://eloquentjavascript.net/contents.html</a></li>
<li>Mozilla's JavaScript Reference <a href="https://developer.mozilla.org/en/JavaScript/Reference" target="_blank">https://developer.mozilla.org/en/JavaScript/Reference</a></li>
<li>JavaScript Koans <a href="https://github.com/liammclennan/JavaScript-Koans" target="_blank">https://github.com/liammclennan/JavaScript-Koans</a></li>
<li>AppendTo's excellent video lessons at: <a href="http://learn.appendto.com" target="_blank">http://learn.appendto.com</a></li>
<li>Nathan's Lessons <a href="http://nathansjslessons.appspot.com/" target="_blank">Interactive JavaScript Lessons</a></li>
<li>JSBin <a href="http://www.jsbin.com/" target="_blank">http://www.jsbin.com</a></li>
</ul>
<p>However I'd be remiss if I left out Douglas Crockford's "<a href="http://shop.oreilly.com/product/9780596517748.do" target="_blank">JavaScript: The Good Parts</a>".</p>
</div>
<div class="slide" id="giveaway">
<h2>Giveaway Time!</h2>
<p class="slide">In this presentation we created a "Robot" constructor function that took a name as a parameter. What was the name of one of the robots we created?</p>
<p class="slide">Question 2 (just in case). Name the 6 data types available in JavaScript.</p>
</div>
<div class="slide" id="questions">
<h1>Questions?</h1>
</div>
<div class="slide" id="fin">
<h2>fin.</h2>
<p>You can view this presentation online at:</p>
<h3><a href="http://bittersweetryan.github.com/art-of-javascript">http://bittersweetryan.github.com/art-of-javascript</a></h3>
</div>
<form action="." method="get" class="goto-form">
<label for="goto-slide">Go to slide:</label>
<input type="number" name="slidenum" id="goto-slide">
<input type="submit" value="Go">
</form>
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>
<p class="deck-status">
<span class="deck-status-current"></span>
/
<span class="deck-status-total"></span>
</p>
<a href="." title="Permalink to this slide" class="deck-permalink">#</a>
<script src="jquery-1.7.min.js"></script>
<script src="modernizr.custom.js"></script>
<script src="extensions/codemirror/codemirror.js"></script>
<!-- Syntax highlighting Modes -->
<!-- javascript -->
<!-- Deck Core and extensions -->
<script src="core/deck.core.js"></script>
<script src="extensions/menu/deck.menu.js"></script>
<script src="extensions/goto/deck.goto.js"></script>
<script src="extensions/status/deck.status.js"></script>
<script src="extensions/navigation/deck.navigation.js"></script>
<script src="extensions/hash/deck.hash.js"></script>
<script src="extensions/codemirror/mode/javascript/javascript.js"></script>
<script src="extensions/codemirror/mode/xml/xml.js"></script>
<script src="extensions/codemirror/mode/css/css.js"></script>
<script src="extensions/codemirror/mode/htmlmixed/htmlmixed.js"></script>
<script type="text/javascript" src="google-code-prettify/prettify.js"></script>
<script src="introduction.js"></script>
<!-- enable codemirror plugin -->
<script src="extensions/codemirror/deck.codemirror.js"></script>
<script src="samples.js"></script>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.