GithubHelp home page GithubHelp logo

javascript's Introduction

Javascript : Test-Driven Learning

This project is aimed to help the user further study Javascript with a test-driven approach. Each unit contains an annotated tutorial and a platform where you can test your understanding of the topic.

Topics

  • Arrays
  • Bad Practices and Solutions
  • Booleans
  • Built-in Functions
  • Closure
  • Comparisons
  • Conditionals
  • Exceptions
  • Falsey Values
  • Functional Javascript (new)
  • Function Expressions
  • Function Expressions as Parameters
  • Functions
  • General Performance
  • Hoisting
  • Logical Assignment
  • Loops
  • Namespaces
  • Numbers
  • Object Prototype
  • Objects
  • Objects Functionality
  • Prototypes
  • Strings
  • Switch Block
  • Ternary Conditionals
  • Truthy Values
  • Variables

Tools

Arrays

  /* An array is a data structure with automatically indexed positions*/
  it('Arrays can be accessed by indices', function () {
    //The brackets indicate to the compiler to make an array and to fill it with
    //the comma-separated values between the brackets
    var arrayOfStrings = [ "StringZero" , "StringOne" , "StringTwo"];
    //We can access any location of the zero-based array
    expect(arrayOfStrings[1]).toBe("StringOne");
  });
  it('You can reference and change specific cells with indices', function () {
    var arrayOfStrings = [ "StringOne" , "StringOne" , "StringTwo"];
    arrayOfStrings[0] = "StringZero"; //You can change the value contained at any index
    expect(arrayOfStrings[0]).toBe("StringZero");
  });

Functions

/*Functions take some input, then execute a series of statements using the input, and outputs a result*/
it('functions help write reusable code', function () {
  expect(addNumbers(1, 2)).toBe(3);
  expect(addNumbers(2, 3)).toBe(5);
  expect(addNumbers(1 + 1, 2 + 1)).toBe(5);//Parameters can also be expressions, which the function will resolve before starting
  var numberOne = 2;
  var numberTwo = 3;
  expect(addNumbers(numberOne, numberTwo)).toBe(5);//Parameters can also be variables
});

// function keyword tells the compiler that you are defining a function
function addNumbers(numberOne, numberTwo) { //The function's name follows the 'function' keyword and should indicate the function's purpose
  //Parameters are passed in a set of parentheses before the first curly brace
  return numberOne + numberTwo;
  //The return keyword works as a terminating statement and exits the function returning the value in front of it
} //The statements that will be executed should be enclosed in curly braces.

Numbers

it('JavaScript uses binary floating point values to handle all of its decimal based operations', function () {
  expect(0.1 + 0.2).toBe(0.30000000000000004);
});
it('You can use the toFixed() method to select the amount of decimal places to display', function () {
  expect((0.1 + 0.2).toFixed(1)).toBe('0.3');
});
it('toFixed() method will round to the last indicated position', function () {
  //0.18 + 0.28 = 0.46
  expect((0.18 + 0.28).toFixed(1)).toBe('0.5');
});
it('parseFloat() turns strings with decimals into numbers', function () {
  expect(parseFloat((0.18 + 0.28).toFixed(1))).toBe(0.5);
});
it('parseInt() looks for the first available integer at the front of a string', function () {
  expect(parseInt("55")).toBe(55);
  expect(parseInt("55 is a great number")).toBe(55);
});
it('if parseInt() does not find an acceptable value at the beginning of a string, it will return a NaN', function () {
  expect(parseInt("A great number, 55")).toBeNaN();
});
it('parseInt() will trim off any decimals that may exist, without rounding', function () {
  expect(parseInt("5.78")).toBe(5);
});
it('parseInt() will accept octal,hexadecimal and decimal values potentially creating undesired results', function () {
  //"021" is read as an octal value(base 8) and converts it to decimal
  expect(parseInt("021")).toBe(17);//This is fixed on ECMAScript5
});
it('you can use a radix value to ensure correct parsing', function () {
  //parseInt will accept any radix value from 2-36 for selecting the Base for the result
  expect(parseInt("021", 10)).toBe(21);
});

Anonymous Closures

//When you create NAMESPACES, the program may still execute its private methods and variables
//It is good practice to use private methods to safely modify private data
//Anonymous Closures allow you to define public and private variables
it('Closures will allow you to make private variables and properties', function () {
  //You can achieve this by surrounding the entire set of properties and values in an immediately
  //invoked function expression
  //The local values and methods will be "closed" into the namespace
  var NAMESPACE = (function () {
    var privateArray = [1, 2, 3];
    var privateVariable = 9;
    //In order to make public properties, you can return an object
    return {
      //Since the function expression is invoked, this returned object will be handled immediately
      // to the NAMESPACE variable and become a namespace
      publicArray: function () {
        return [4, 5, 6];
      },
      publicVariable: 10 + privateVariable
    };
  })();//These parentheses indicate that the function expression should be immediately executed
  //Since privateArray and privateVariable are private, we expect them to be undefined
  expect(NAMESPACE.privateArray).toBeUndefined();
  expect(NAMESPACE.privateVariable).toBeUndefined();
  expect(NAMESPACE.publicArray()).toEqual([4, 5, 6]);
  expect(NAMESPACE.publicVariable).toBe(19);
});

Prototypes

/*Class :  Set of Objects that inherit properties from the same prototype*/

  it('You can create Constructors that allow to set up inheritance while also assigning specific property values', function () {
    //Capitalizing this function's name distinguishes it as a maker of an entire "Class" of objects
    function Person (firstName, lastName ,age){
      //'this' keyword inside a constructor will automatically refer to the new instance of the class that is being made
      this.firstName = firstName;
      this.lastName = lastName;
      this.age = age;
    }

    //'new' keyword produces a new Object of the specified class
    var martinPerson = new Person("Martin", "Chavez", 27);

    expect(martinPerson.firstName).toBe("Martin");
    expect(martinPerson.lastName).toBe("Chavez");
    expect(martinPerson.age).toBe(27);
  });

  it('You can assign a prototype to a constructor', function () {
    function Person (firstName, lastName ,age){
      this.firstName = firstName;
      this.lastName = lastName;
      this.age = age;
    }
    //Setting a constructor prototype property allows the instances to access these properties
    Person.prototype = {
      address: "House 123"
    };
    var martinPerson = new Person("Martin", "Chavez", 27); //There is no need to define the address for each person
    expect(martinPerson.address).toBe("House 123");

  });
  it('You can modify the message functions in a prototype to use the data values in the calling instance', function () {
    function Person (firstName, lastName){
      this.firstName = firstName;
      this.lastName = lastName;
    }

    Person.prototype = {
      //'this' keyword searches for the particular Object(Person) that called the inherited function and retrieves the data from it
      fullName: function() { return(this.firstName + " " + this.lastName); }
    };
    var martinPerson = new Person("Martin", "Chavez");

    expect(martinPerson.fullName()).toBe("Martin Chavez");
  });

  it('You can use prototype chaining to reuse functionality', function () {
    function Person (firstName, lastName){
      this.firstName = firstName;
      this.lastName = lastName;
      this.blackHair = true;
    }

    function Baby(firstName, lastName){
      //You can call the Person constructor within the Baby constructor
      Person.call(this,firstName, lastName);
      // We need to add a reference to this Object constructor, otherwise it will use the Person constructor
      this.constructor = Baby;
    }

    // By setting a parent object as a constructors prototype, objects build with that construct gain access to
    // all the methods on that object, including the methods on its constructor prototype.
    Baby.prototype = new Person();

    // You can also add specific methods to this prototype
    Baby.prototype.cry = function(){
      this.isCrying = true;
    };

    var baby = new Baby("Martin", "Chavez");
    baby.cry();

    // Property from the Baby object
    expect(baby.isCrying).toBeTruthy();
    expect(baby.firstName).toBe("Martin");
    expect(baby.lastName).toBe("Chavez");
    expect(baby.constructor).toBe(Baby);
    // Property from the Person object
    expect(baby.blackHair).toBe(true);
  });

Install (Works on any platform)

npm install --global npm@latest (if you don't have it already)
npm install --global yo bower grunt-cli
cd LearnJavascript
npm install
bower install

Run the Tests

grunt test

Run the tests

Author

Martin Chavez

Continue Learning

javascript's People

Contributors

hzooly avatar martinchavez avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

javascript's Issues

License

Hi, I don't see License on this repository, or in https://github.com/MartinChavez/Javascript.

I suggest to have License in this repository. Good for tutorial have a license. You can add LICENSE file to your repository. LICENSE can fit to you is MIT License. If you want me to add the license, I happy to add that.

Fix content from feedback

The section on Bad practices is somewhat weak. The comments only point to performance and legibility issues with eval and with.

In 4 - Loops, the assertions are not too well chosen. You're testing that...

expect(currentNumber).toBe(5);

...while, to be a better exemplification of what while and for do, a more correct assertion would be to...

expect(currentNumber < 5).toBe(false); // or more generally, expect(condition).toBe(false);

That way we're actually asserting on the contract of while/for not on the effects that happened.
The optimization proposed by 'You can minimize memory access inside for loops' has been demonstrated to not be such an optimization.

The for-in example is under Performance optimizations but the argument is not related to performance.

In 07 - Arrays the test 'Arrays can hold different types of variables' can be confusing. Arrays hold different types of values. In fact, in JavaScript types are related to values, never to variables.
In 14 - Objects Functionality some of the tests are all over the place. 'Properties can be functions' does not actually test that a property is a function at all, but instead it tests the behaviour of thisValue when actually calling the function on the object. Also, it can be particularly confusing the comment that //'this' keyword always refers to the owner Object of the function as it introduces some mysterious "owner object" concept which goes unexplained (and is probably wrong anyway). The comment that //'this' keyword references the person's object doesn't help much either.
The test 'To iterate through an object we need to use the for-in loop' introduces iterating through object properties with for-in but obfuscates the assertion too much because the test is not very good. It also seems it would make more sense to put this test in 13 - Objects than here.

15 - Object prototype has some problems too.
The assertions for 'you can use valueOf to retrieve the primitive type associated with an object' don't actually relate to "retrieving a type", but instead assert something on the workings of == vs ===. Also, saying expect(fiveNumber.valueOf()).toBe(5) is related to retrieving the primitive type of an object is, to say the least, confusing.

Saying that 'you can use valueOf to retrieve the type of an object' (emphasis is mine) is quite confusing. More so when the assertion shows that person (which we would probably think is of type Person) is shown to apparently be of type Object.
In general, I'm getting the impression that most if not all of the mentions on the word type are either wrong or confusing, when not both.
The rest of the tests in this section have some additional issues both in the wording and in the content.

Section 17 - Prototypes is, quite frankly, a mess. 'Properties can be functions' doesn't even make sense in the description itself and the assertions it performs don't seem to clarify at all what that description is supposed to mean. The test 'Adding a new function into the Strings Prototype' should instead be named after the comment it has right before it (You can add base functionality to all objects of the same type). I don't even know what 'You can create generic objects and build all the inherited objects with such properties' means. 'You can use prototype chaining to reuse functionality' doesn't seem to be showing any reuse of functionality.

Some of this may be a symptom of what I said that I feel a test driven approach doesn't really help for some of these explanations.
The only thing really worth in 19 - General performance is the bit about using DOMFragments.
In 26 - Truthy values this piece here...
var definedVar = value ;
value = (definedVar) ? true : false;
expect(value).toEqual(true);
...could be confusing. It may seem to be saying that we're expecting the result to be true just because we're testing a defined variable. While it is actually true because definedVar has a value of true.

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.