Code Monkey home page Code Monkey logo

wdi_6_js_demo_basics's Introduction

General Assembly Logo

JavaScript Basics

JavaScript is a high-level programming language like Ruby, but with a very different syntax and different ways of dealing with objects. It is also the only language understood by web browsers, so JavaScript is crucial in writing web applications that respond immediately to user actions, without having to wait for a server to send back a whole new HTML page.

Objectives

By the end of this lesson, students should be able to:

  • List the Javascript datatypes
  • Manipulate JavaScript datatypes
  • Write conditionals to manage control flow in javascript
  • Describe the difference between loose and strict equality
  • Read and write javascript arrays
  • Read and write javascript objects

Instructions

  • Fork, clone your fork
  • cd into your local copy
  • run npm install
  • run bower install
  • run grunt test
  • Follow along with the README and make the tests pass.

Running JavaScript

When developing in Ruby, we'd run code files by typing ruby some_file.rb. We can do something similar with JavaScript by typing node some_file.js. This runs the file through NodeJS, a framework that can run JavaScript outside of a web browser. This is useful when developing JavaScript applications that run on a server – but since we'll mostly be using JavaScript in the browser, we'll rarely use this method.

  • Try it: Examine the contents of app/js/testrun.js. Then type node testrun.js in your terminal and you should see "It works!"

Browsers run JavaScript when they see a <script> tag in a web page that points to the URL of a JavaScript file. The browser will make a separate request to download the file, run it, then proceed with parsing the rest of the page.

There is no "terminal" in the browser, but there is something called the console that shows output and errors from JavaScript programs. It also lets us type in and run JavaScript code one line at a time, like Ruby's pry.

  • Try it: Examine the contents of app/testrun.html. Then open this file in your browser. Press Cmd+Opt+I (Mac) or Ctrl+Shift+I (Linux) to open the console (depending on which browser you're using), and you should see "It works!"

Note: If you type node in your terminal without specifying a filename, it will let you enter and run JavaScript one line at a time just like the browser console.

Data Types

Like Ruby, in JavaScript everything is an object. Unlike Ruby, in JavaScript there is no such thing as a "class" – each object stands alone, and can have properties and behaviors unique to it. We can still create something that looks and acts a lot like a class, but we'll get into this in a later lesson.

There are some special objects in JavaScript called "primitives", also known as the standard data types.

The latest ECMAScript standard defines seven data types:

  • Six data types that are primitives:
    • Number
    • String
    • Boolean
    • Undefined
    • Null
    • Symbol (new in ECMAScript 6)
  • and Object

Dynamic Typing

JavaScript is a loosely typed or a dynamic language. That means you don't have to declare the type of a variable ahead of time. The type will get determined automatically while the program is being processed. That also means that you can have the same variable as different types:

var foo = 42;    // foo is a Number now
var foo = "bar"; // foo is a String now
var foo = true;  // foo is a Boolean now

Numbers

In app/js/app.js follow along and write this code.

'use strict';

/* NUMBERS
———————————————————————————————————————————————————
Unlike in Ruby there is no special distinction between numbers with and
without decimal points. They are all just "numbers".  */

var currentLevel = 17;
var price = 1499.99;
var fiveMinutes = 60 * 5; // all the basic math operations work
var threeHalves = 3 / 2; // this results in 1.5 -- no weird "integer division"
price = 1299.99; // only the first assignment needs a `var`
price += 100; // this kind of shortcut still works

/*  There is only 1 integer that has two representations: 0 is represented
as -0 and +0. ("0" is an alias for +0).

*/

var infinity = 42 / +0;
var negativeInfinity = 42 / -0;

Run grunt test. If there are any failing tests go back and fix your code.

Strings

In app/js/app.js add this code.

/* STRINGS
———————————————————————————————————————————————————
Unlike in Ruby there is no difference between single quotes and double
quotes... since JavaScript has no string interpolation. Strings are also
"immutable", meaning we can't modify them in-place (no shoveling!)  */

var greeting = 'Hello there!';
var firstName = "Jason";
var lastName = "Wharff";
var myName = firstName + ' ' + lastName; // clunky, but it's the only way

Run grunt test. If there are any failing tests go back and fix your code.

Booleans

In app/js/app.js add this code.

/*  BOOLEANS
———————————————————————————————————————————————————
Like in Ruby, we have the booleans true and false. */

var excited = true;
var testMode = false;

var excitedlyTesting = excited && testMode; // boolean && and || are here
var calm = !excited; // boolean "not" is also here

Run grunt test. If there are any failing tests go back and fix your code.

Undefined

In app/js/app.js add this code.

// Unlike in Ruby, we have an extra nil-like value called "undefined". It's
// what you'll get if you access a variable that's not assigned yet, or call
// a function that doesn't return anything.
var mystery = undefined;
var spooky; // This does the same thing as above! The value is "undefined"

Run grunt test. If there are any failing tests go back and fix your code.

Null

In app/js/app.js add this code.

/*  NULL
———————————————————————————————————————————————————
The value null is a JavaScript literal representing null or an "empty" value, 
i.e. no object value is present. It is one of JavaScript's primitive values.
We also have nil, but in JS it's called "null". A value that carries no value.
Like undefined, but defined (not automatically assigned).
It is falsy.  */
var result = null; // the variable `result` is defined, but it's value is null.
console.log(typeof undefined);

Run grunt test. If there are any failing tests go back and fix your code.

We already have some notable syntax differences from Ruby:

  • Variable and function names use lowerCamelCase rather than snake_case. This is a much weaker convention in JavaScript than snake case in Ruby – although it's the style used by the language itself, many JavaScript developers use snake case anyway.
  • Lines of code usually end in a semicolon. We can leave these out, but JavaScript will be left to guess where they should be inserted, and sometimes it guesses wrong. The rules for when to use a semicolon are hard to remember, but your JSHint plugin for Sublime Text will steer you right.
  • The first time we assign a variable (and only the first time), we must prefix the assignment with var. This is known as "declaring" the variable. As with semicolons, if you don't do this your program will still work sometimes, but not always. We'll get into why this is when we talk about functions.

A common theme in JavaScript is "things you can easily get wrong and have your program usually still work, but sometimes not". Attention to detail is your ally when writing JavaScript.

Control Flow

In app/js/app.js add this code.

/*  Control Flow in Javascript
———————————————————————————————————————————————————
Important differences from Ruby:
  - Conditions must be enclosed in parentheses.
  - Code blocks are always enclosed in braces. There is no `end` in JavaScript.
  - The "else-if" syntax is two separate words, `else if`, rather than `elsif`.
  - There is no `unless` in JavaScript. Use the "not" operator (`!`) instead.   */

var holyNumber = function(holyNumber){
  if(holyNumber > 3) {
    return 'Four shalt thou not count. Five is right out.';
  } else if(holyNumber < 3) {
    return 'Count neither one nor two, excepting that thou then proceedest to three.';
  } else if(holyNumber === 3) {
    return 'Throw the holy hand grenade!';
  } else {
    return 'World ends';
  }
};

holyNumber('4'); // 'Four shalt thou not count. Five is right out.'
holyNumber(4); // 'Four shalt thou not count. Five is right out.'
holyNumber('2'); // 'Count neither one nor two, excepting that thou then proceedest to three.'
holyNumber(2); // 'Count neither one nor two, excepting that thou then proceedest to three.'
holyNumber('3'); // 'World ends'
holyNumber(3); // 'Throw the holy hand grenade!'

Run grunt test. Then look at the tests on lines 106–119. Note the difference in datatypes passed into the function call. Some are strings, some are numbers, but Javascript converts the datatypes when the ">" or "<" are used.

Less-Used Flow Control

JavaScript also has while loops (but no until loops).

There are no tests for while loops. If you're interested in testing this code, run grunt serve in the root of your repo, then uncomment this code in index.html

var input = '';
while(input !== 'stop') {
  input = prompt('Enter "stop" to cut it out');
}

Instead of case/when, JavaScript has switch/case (just to trip you up).

In app/js/app.js add this code.

/*  Switch/Case statements
———————————————————————————————————————————————————
Note that `case` blocks are *not* enclosed in braces,
and each one also needs a `break` statement at the end &ndash;
otherwise code execution will "fall through" to the next
block and keep on going! Thankfully `switch` uses the
threequals for comparison, but due to its quirks and
inflexibility, you don't see it that often in real-world programs.
*/

var yearbook = function(year){
  switch(year) {
    case 'freshman':
      return 'cannon fodder';
      break;
    case 'sophomore':
      return 'mildly respectable';
      break;
    case 'junior':
      return 'some influence';
      break;
    case 'senior':
      return 'phenomenal cosmic power';
      break;
    default:
      return 'mysterious stranger'
      break;
  }
};

Run grunt test. If there are any failing tests go back and fix your code.

Loose vs. Strict equality operators

Notice above that even though holyNumber is a string, we can use the > and < operators to compare it with numbers. This is because most JavaScript comparison operators, including ==, are "loose" – meaning JavaScript will try to convert both sides of the operator to the same data type before evaluating. This has some counter-intuitive consequences.

In app/js/app.js add this code.

// All of these are true
3 == '3'
0 == false
1 == true
2 != true
2 != false
0 == ''
0 == []
'' == []
'wat' == ['wat']
null == undefined

Fortunately, JavaScript also has the === operator, known as the "strict" equality operator or the "threequals", which does not attempt to convert data types and works much closer to Ruby's notion of equality. Always use this operator to check equality!

There is also a "strict" not-equal operator, !==. Unfortunately, there are no strict greater-than or less-than operators, so we kind of have to live with the data type conversion when using those.

// Never use these operators
3 == '3' // true
1 != '1' // false

// Always use these operators
3 === '3' // false
1 !== '1' // true

Run grunt test. If there are any failing tests go back and fix your code.

Arrays

JavaScript arrays work mostly the same as Ruby arrays.

In app/js/app.js add this code.

/*  Arrays
———————————————————————————————————————————————————
Like all objects, arrays can have *functions* (or methods) 
defined on them, like `.sort()`, that we can call. Functions 
must always be called with parentheses, even if we're not 
passing any arguments. Note `length` is not a function &ndash; 
instead it is a *property* that is accessed directly, and we 
cannot use parentheses to call it. The MDN reference will 
tell you whether something is a property or a function. */

var colors = ['red', 'green', 'blue'];
var green = colors[1];
var colorsCount = colors.length;
var indexOfBlue = colors.indexOf('blue');
var lastColor = colors[colors.length - 1]; // we can't use negative indexes

colors.push('purple');
var purple = colors.pop();

colors.sort(); // now they're in alphabetical order

// These should be familiar from Ruby
var newColors = 'blue, orange, yellow'.split(', ');
var joinedColors = newColors.join(' and '); // 'blue and orange and yellow'

Run grunt test. If there are any failing tests go back and fix your code.

Iterating through an array

In app/js/app.js add this code.

/*  Iterating through arrays
———————————————————————————————————————————————————
In Ruby we avoid `for` loops in favor of methods like
`each` or `map`, but in JavaScript they are seen frequently
for simple iteration.
*/
var colors = ['red', 'green', 'blue'];
var tmpColors = [];
for(var i = 0; i < colors.length; i++) {
  tmpColors.push(colors[i] + ' is one of my favorite colors');
}

/*  The three semicolon-separated components of a `for` loop are:
- A statement that will be executed once before the first iteration
- An expression evaluated at the start of each iteration &ndash; if `false`, the loop is terminated
- A statement that will be executed at the start of each iteration

Since `for` loops are awkward and error-prone, it's usually
preferable to use the `forEach` function instead. This requires
defining an anonymous function, which we'll get into later.
`forEach` can also receive the index and the array iterating upon as params
There are also `map` and `reduce` functions that do the same thing
as their Ruby equivalents.  */

var tempColors = [];
colors.forEach(function(color, index, array){
  tempColors.push(color + ' is favorite color number ' + index);
});

The three semicolon-separated components of a for loop are:

  • A statement that will be executed once before the first iteration
  • An expression evaluated at the start of each iteration – if false, the loop is terminated
  • A statement that will be executed at the start of each iteration

Since for loops are awkward and error-prone, it's usually preferable to use the forEach function instead. This requires defining an anonymous function, which we'll get into later.

There are also map and reduce functions that do the same thing as their Ruby equivalents.

Run grunt test. If there are any failing tests go back and fix your code.

JS Objects

In app/js/app.js add this code.

There is no such thing as a hash in JavaScript. That said, consider the following:

var friend = {
  name: 'Dan',
  age: 26,
  colors: ['purple', 'blue', 'teal'],
  pets: [
    { name: 'Fattykins', species: 'cat', age: 6 },
    { name: 'Reginald', species: 'hamster', age: 2 }
  ]
};

Looks like a hash, right? Nope! It's actually a plain object. As we mentioned above, objects in JavaScript can have properties. In this example, name, age, and so on are not "keys" but property names. Each property has a value, like the keys in a Ruby hash have values.

Some important differences to note:

  • Though the property names look like Ruby symbols, they're actually an alternate syntax for strings.
  • This is the only syntax to define object properties – there is no "hash rocket".
  • Bracket notation is not the only way we can access object properties. Take a look:
var secondColor = friend.colors[1];
var firstPetAge = friend.pets[0].age;
friend.colors.push('indigo');

This style is preferred over the bracket style where possible. It should also look familiar: We used the same syntax to get the .length of an array, which we mentioned was a property.

Operations on Objects

In app/js/app.js add this code.

/*  Operating on Objects
———————————————————————————————————————————————————
Plain objects in JavaScript are extremely minimal and
have virtually no functions defined on them (unlike Ruby
hashes, which have dozens!). We can at least iterate
over the properties of any object using a `for...in` loop:
*/
var propArray = []
for(var prop in friend) {
  propArray.push("My friend's " + prop + " is " + friend[prop]);
}

And we can remove properties of any object using the delete operator:

console.log(friend.age); // 26
delete friend.age;
console.log(friend.age); // undefined

Since these are plain objects and not hashes, two objects are only considered equal if they are actually the same object (even if we compare with ==):

var friend1 = { name: 'Dan', age: 26 };
var friend2 = { name: 'Dan', age: 26 };

console.log(friend1 === friend2); // false
friend2 = friend1;
console.log(friend1 === friend2); // true

wdi_6_js_demo_basics's People

Contributors

grantovich avatar fishermanswharff avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.