Skip to content

Instantly share code, notes, and snippets.

@snodnipper
Created July 30, 2016 10:35
Show Gist options
  • Save snodnipper/252e436d587ab0e42b7ad3231034e8c3 to your computer and use it in GitHub Desktop.
Save snodnipper/252e436d587ab0e42b7ad3231034e8c3 to your computer and use it in GitHub Desktop.
Notes from the Modern Javascript Class - http://courses.angularclass.com/courses/modern-javascript
Course notes from http://courses.angularclass.com/courses/modern-javascript
Afterwards, we are encourage to complete: http://courses.angularclass.com/courses/angular-2-fundamentals
Note: not repeating too much here - just points to remember!
---
npm init <-- initialize a package.json by the CLI
npm run build <-- build just sits within package.json...and could be a simple "echo hello world"
'dependencies' are always downloaded for the package. devDependencies are only installed when developing.
Use --save OR --save-dev to save packages without our package.json
For example:
npm install underscore --save
npm install lodash --save-dev
Uninstall: npm uninstall and npm uninstall --global
[JS dudes love promises. I think we'll jump straight to RxJs. They love observables too!]
# Package for webpage #
webpack - package all our JS as one.
npm install webpack
For example: webpack app.js dist/app.bundle.js
You would update the HTML to point to <script....dist/app.bundle.js....
For configuration, you can use: webpack.config.js - which saves you from using the CLI
e.g. the output path to be './dist' and the filename to be 'app.bundle.js'
Then you can just run webpack again.
You can also add require('./another-folder/sub-folder'); to your app.js entry and it will package up just fine.
You can also create different 'entry points' to output JS for different apps, such as filename [name].bundle.js - where name is populated for the different apps.
---
So typing webpack is tedious...so what you can do it type 'webpack --watch' _but_ that means we have to refresh everytime there is a change in the browser!
Webpack provides a development server: webpack-dev-server - which will rebuild in memory to speed things up.
npm install webpack-dev-server -g
can use 'webpack-dev-server --output-public-path dist' to ensure that files in that directory are served
finally, we can use: 'webpack-dev-server --output-public-path dist --inline' to ensure that every time we press save we have the latest code in the browser. It quite literally 'inlines' some code in the page.
webpack has the notion of loaders to transform code. Node only parses JSON _but_ using raw-loader we can put HTML into JS. We can then do:
var options = {
search 'Hello World',
replace: 'Hello Webpack'
};
...
loaders: [
'raw-loader',
'string-replace-loader?' + JSON.stringify(options)
]
Which allows text to be replaced.
Note: loaders transform code on a per module basis whereas plugins have full reign and can transform at a global level (so anything)
one such plugin is UglifyJs, which will minify the code.
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
===========================
ES5 - Object.keys - outputs the objects keys into an array
var obj = {
a:7
get b() {
return this.a + 1
}
set b(x) {
this.a = x / 2
}
}
console.log(obj.a); //7
console.log(obj.b); //8
----
Variable declarations in ES2015 - var, let & const
var - variable, can be reassigned. variable hoisting sounds like filth and can reassign if you are not careful!
let - has block scoping to provide expected behaviour, just like in Java!
const - constant, if you try to reassign you will get an error!
When using ES2015 you should always use `let` and `const` instead of var!
----
Template Strings. Backticks!
Template strings are the use of the back-tick symbol (`) to open and close a multi-line string. Template strings also allow for string interpolation using the $ { data } syntax.
==============
var myData = {
data: 'hello'
}
var template = `
<div>
${ myData.data }
</div>
`
console.log(template)
==============
Arrow functions: new syntax for maintaining scope within callback functions - a common problem with async JS.
Prior to arrow functions would could ".bind(this)" to ensure that the "this" reference was maintained in nested objects.
==============
ES2015 - we have classes! Just syntactical sugar over JS existing prototype based inheritance.
new syntax:
class App {
constructor() {
console.log('hello');
}
method() {
console.log('method called');
}
}
old syntax:
function App() {
console.log('hello');
}
App.prototype.method = function() {
console.log('method called');
};
var app = new App();
app.method();
=============
ES2015 - modules: allow code sharing between JavaScript files. Very simply it is about importing and EXPORTING!
// require files
import something from 'framework'; // importing 'something' from the file that is called 'framework'
import * as something from 'framework';
import {matchPro} from 'framework';
// expose values
export default function something {}
export var value = 'value';
export var another = 'value2';
export var matchedPro = 'someValue';
exporting is about exposing a value or a class that you need to inject into another place
===========
ES2015 destructuring - is a way to pluck properties off of a data structure and assign them to distinct variables.
The following two are the same.
ES6:
var object = {
"a": 1,
"b": 2
}
var {a, b} = object;
console.log(a, b);
ES5:
var object = {
"a": 1,
"b": 2
}
var a = object.a;
var b = object.b;
console.log(a, b);
Nice example (to keep things less verbose):
var prism = {
l: 5,
w: 8
}
// note default height is 10
function rectPrismArea({l, w, h = 10}) {
return l * w * h;
}
console.log(rectPrismArea(prism));
===============
ES2015 Rest Parameters. Nothing to do with REST Apis! It is to do with 'the rest of the parameters passed into a function'.
Same as Java really. Example:
printArguments(1, 2, 3)
function printArguments(...args) {
args.forEach(function(arg) {
console.log('rest args:', arg)
});
}
// rest args: 1
// rest args: 2
// rest args: 3
in old land folk did:
funtion printArguments() {
var args = [].slice.call(arguments, 0);
...
And of course you can do:
function printObjects(prefix, ...args) {
...
=====================
ES2015 Spread Operator - conceptually the opposite of rest parameters - it is the "dynamic expansion of an expression"
Example:
let nums = [1, 2, 3];
function addEverything(x, y, z) {
return x + y + z;
}
let val = addEverything(...nums);
console.log(val);
// 6
=====================================
ES2015 - enhanced object literals
ES6:
var obj = {
property: 'first prop'.
[ 'prop_' + 42 ]: 'life'
};
console.log(obj);
ES5:
var obj = {
handler: function() {}
};
obj[ 'prop_' + 42] = 42;
console.log(obj.prop_42);
==================
#############
# TypeScript
#############
A superset of JavaScript and sits on top of ES2015. So lets compare:
var name = 'jen'; --> var name: string = 'jen';
var age = 23; --> var age: number = 23;
var flag = false; --> var flag: boolean = false;
Lets make a log for strings function:
const log = (item: string) => {
console.log(item);
}
log(); // supplied parameters do not match signature of call target
log("whoop whoop");
How about returning of a specific type?
In the previous example, the following is inferred:
const log = (item: string) => { --> const log = (item: string): void => {
but we can change that to, say:
const log = (item: string): string => {
return item + " whoop";
}
We can also assign types to arrays:
const names: string[] = [];
names.push("dave");
names.push(3); // blows up
TypeScript can also infer the type:
const names = ['name'];
==============================
TypeScript Interfaces
Basically ensure that our object properties adhere to the interface. For example:
interface BakedGood {
sugar: number;
name: string;
bake(mins: number): string;
icing?: boolean; // <-- this is optional so you don't have to adhere
}
const cake: BakedGood = {}; // does not adhere to the interface
const cake: BakedGood = {
sugar: 23,
name: 'cherry cake',
bake(min: number) {
return `will be done in ${min}...`
}
}
===========================
TypeScript - classes
Basically, takes advantage of ES2015 classes _but_ adds more magic. For example:
class Car {
constructor(make, year){}
}
we can add some type checking:
class Car {
constructor(make: string, year: number){}
}
so lets enhance:
class Car {
make: string;
constructor(make: string, year: number) {
this.make = make
}
}
But how about reducing the text? It does the same as above.
class Car {
constructor(public make: string, public year: number) { }
}
We can also use the private keyword:
class Car {
constructor(public make: string, private year: number) { }
}
Or protected:
class Car {
constructor(public make: string, protected year: number) { }
}
Lets create a class that implements an interface with all that type checking gorgeousness:
interface Vehicle {
make: string;
year: number;
type: string; // you could make that optional with: "type?: string;"
go(): void;
}
class Car implements Vehicle {
type: string = ''; // with default value of nothing
constructor (public make: string, public year: number) {
}
go(): void {
}
}
========================
TypeScript - Decorators
Decorators are part of the ES2016 proposed spec but TypeScript went ahead and implemented them anyway.
A decorator is a function that is going to decorate (populate) a target.
A target can be: class, property, method, parameter, accessor (getter or setter)
A decorator might look like:
/**
*@param target one of class, property, method, parameter, accessor (getter or setter)
*@param key if target is a function then you get the name of the function property. If a variable you get the name of the property etc.
*@param descriptor the function or the method itself
*/
function myDecorator(target, key, descriptor) {
}
For example:
function clean(target) {
target.cleaned = true;
}
@clean
class Animal {} // cleaned will be set to true
You can also stack decorators:
@clean @dirty
class Animal {}
or
@clean
@dirty
class Animal {}
Another example:
function clean(value: boolean) [
return function (target) {
target.cleaned = value;
}
}
@clean(true)
class Animal {
open() {}
}
=============================
TypeScript - static properties
Note: course material does not exist yet. That said:
The classes you create in TypeScript can either contain static members or instance members.
For example:
class Animal {
id: number;
name: string;
static classification: string;
static displayClassification() {
alert(Animal.data);
}
}
Modern JavaScript DONE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment