Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Key Points

  1. run js using node as a file
  2. run js in web page on javascript console ( eg Firefox browser etc )

References

...

JS modules

...

https://github.com/lukehoban/es6features#readme

http://es6-features.org/#Constants

...

https://medium.com/engineered-publicis-sapient/javascript-es6-es7-es10-where-are-we-8ac044dfd964

js-versions-es10-2019-medium.com-JavaScript ES6 ES7 ES10 where are we.pdf

...

Javascript debugger for web pages in Firefox

better than js console

...

3 dots on parms input are rest parameters gathered automatically into an array

rest parms can be destructured into variables

spread operator expands elements of an iterable where multiple elements are used

...

https://medium.com/javascript-scene/what-is-webassembly-the-dawn-of-a-new-era-61256ec5a8f6

https://webassembly.org/

https://developer.mozilla.org/en-US/docs/WebAssembly

...

Key Concepts

Javascript Basics

Testing Node shell

open

run needed npm installs

> var stringer = require('node-csv').Stringifier;
> fs.writeFile('./msgsout.txt', JSON.stringify(msgs), (err) => { console.log(err) });
> fs.appendFile('./msgsout.txt', JSON.stringify(msgs), (err) => { console.log(err) });
> fs.appendFile('./msgsout.txt', JSON.stringify('more data 1 \n'), (err) => { console.log(err) });

Data Types

Data Types can be converted

https://gomakethings.com/converting-strings-to-numbers-with-vanilla-javascript/

> var a = "12";
> var b = "44";
> var c = Number(a) + Number(b)
> console.log(`var c = ${c}`);
var c = 56

methods to convert strings to numbers

parseInt 

parseFloat 

Number

Promises

https://developers.google.com/web/fundamentals/primers/promises

At their most basic, promises are a bit like event listeners except:

  • A promise can only succeed or fail once. It cannot succeed or fail twice, neither can it switch from success to failure or vice versa.
  • If a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called, even though the event took place earlier.

This is extremely useful for async success/failure, because you're less interested in the exact time something became available, and more interested in reacting to the outcome.

A promise can be:

  • fulfilled - The action relating to the promise succeeded
  • rejected - The action relating to the promise failed
  • pending - Hasn't fulfilled or rejected yet
  • settled - Has fulfilled or rejected

The spec also uses the term thenable to describe an object that is promise-like, in that it has a then method

Promise example

You can transform values simply by returning the new value:

...

Simplifying Promise sequences

https://developers.google.com/web/fundamentals/primers/promises

The response is JSON, but we're currently receiving it as plain text. We could alter our get function to use the JSON responseType, but we could also solve it in promises land:

get('story.json').then(function(response) {
 
return JSON.parse(response);
}).then(function(response) {
  console
.log("Yey JSON!", response);
})

Since JSON.parse() takes a single argument and returns a transformed value, we can make a shortcut:

get('story.json').then(JSON.parse).then(function(response) {
  console
.log("Yey JSON!", response);
})

In fact, we could make a getJSON() function really easily:

function getJSON(url) {
 
return get(url).then(JSON.parse);
}

getJSON() still returns a promise, one that fetches a url then parses the response as JSON.

How Promises work in sequence with then

You can also chain thens to run async actions in sequence.

When you return something from a then() callback, it's a bit magic. If you return a value, the next then() is called with that value. However, if you return something promise-like, the next then() waits on it, and is only called when that promise settles (succeeds/fails). For example:

getJSON('story.json').then(function(story) {
 
return getJSON(story.chapterUrls[0]);
}).then(function(chapter1) {
  console
.log("Got chapter 1!", chapter1);
})

Here we make an async request to story.json, which gives us a set of URLs to request, then we request the first of those. This is when promises really start to stand out from simple callback patterns.

You could even make a shortcut method to get chapters:

...

We don't download story.json until getChapter is called, but the next time(s) getChapter is called we reuse the story promise, so story.json is only fetched once. Yay Promises!

Prior to promises, we registered callbacks for events

...

This doesn't catch images that error'd before we got a chance to listen for them; unfortunately the DOM doesn't give us a way to do that. Also, this is loading one image, things get even more complex if we want to know when a set of images have loaded.

JS Modules - export and import system for reusable modules

https://v8.dev/features/modules

Export something to external clients

Within a module, you can use the export keyword to export just about anything. You can export a const, a function, or any other variable binding or declaration. Just prefix the variable statement or declaration with export and you’re all set:

// 📁 lib.mjs
export const repeat = (string) => `${string} ${string}`;
export function shout(string) {
return `${string.toUpperCase()}!`;
}

Import something to a client

You can then use the import keyword to import the module from another module. Here, we’re importing the repeat and shout functionality from the lib module, and using it in our main module:

// 📁 main.mjs
import {repeat, shout} from './lib.mjs';
repeat('hello');
// → 'hello hello'
shout('Modules in action');
// → 'MODULES IN ACTION!'

Module concepts

  • Modules have a lexical top-level scope. This means that for example, running var foo = 42; within a module does not create a global variable named foo, accessible through window.foo in a browser, although that would be the case in a classic script.

  • Similarly, the this within modules does not refer to the global this, and instead is undefined. (Use globalThis if you need access to the global this.)

  • The new static import and export syntax is only available within modules — it doesn’t work in classic scripts.

Using JS modules in a browser

On the web, you can tell browsers to treat a <script> element as a module by setting the type attribute to module.

<script type="module" src="main.mjs"></script>
<script nomodule src="fallback.js"></script>

Browsers that understand type="module" ignore scripts with a nomodule attribute. This means you can serve a module-based payload to module-supporting browsers while providing a fallback to other browsers.

Dynamic import

only load module when called. Loaded module will be cached in browser session.

<script type="module">
(async () => {
const moduleSpecifier = './lib.mjs';
const {repeat, shout} = await import(moduleSpecifier);
repeat('hello');
// → 'hello hello'
shout('Dynamic import in action');
// → 'DYNAMIC IMPORT IN ACTION!'
})();
</script>

import.meta - get metadata on a module

Another new module-related feature is import.meta, which gives you metadata about the current module. The exact metadata you get is not specified as part of ECMAScript; it depends on the host environment. In a browser, you might get different metadata than in Node.js, for example.

Javascript Async Functions

https://developers.google.com/web/fundamentals/primers/async-functions

Async functions work like this:

async function myFirstAsyncFunction() {
 
try {
   
const fulfilledValue = await promise;
 
}
 
catch (rejectedValue) {
   
// …
 
}
}

If you use the async keyword before a function definition, you can then use await within the function. When you await a promise, the function is paused in a non-blocking way until the promise settles. If the promise fulfills, you get the value back. If the promise rejects, the rejected value is thrown.

Async functions vs Promises - which reads easier?

Say we wanted to fetch a URL and log the response as text. Here's how it looks using promises:

function logFetch(url) {
 
return fetch(url)
   
.then(response => response.text())
   
.then(text => {
      console
.log(text);
   
}).catch(err => {
      console
.error('fetch failed', err);
   
});
}

And here's the same thing using async functions:

async function logFetch(url) {
 
try {
   
const response = await fetch(url);
    console
.log(await response.text());
 
}
 
catch (err) {
    console
.log('fetch failed', err);
 
}
}

Default + Rest + Spread

Callee-evaluated default parameter values. Turn an array into consecutive arguments in a function call. Bind trailing parameters to an array. Rest replaces the need for arguments and addresses common cases more directly.

function f(x, y=12) {
  // y is 12 if not passed (or passed as undefined)
  return x + y;
}
f(3) == 15
function f(x, ...y) {
  // y is an Array
  return x * y.length;
}
f(3, "hello", true) == 6
function f(x, y, z) {
  return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6

More MDN info: Default parameters, Rest parameters, Spread Operator

Generators

Generators simplify iterator-authoring using function* and yield. A function declared as function* returns a Generator instance. Generators are subtypes of iterators which include additional next and throw. These enable values to flow back into the generator, so yield is an expression form which returns a value (or throws).

Note: Can also be used to enable ‘await’-like async programming, see also ES7 await proposal.

var fibonacci = {
  [Symbol.iterator]: function*() {
    var pre = 0, cur = 1;
    for (;;) {
      var temp = pre;
      pre = cur;
      cur += temp;
      yield cur;
    }
  }
}

for (var n of fibonacci) {
  // truncate the sequence at 1000
  if (n > 1000)
    break;
  console.log(n);
}

The generator interface is (using TypeScript type syntax for exposition only):

interface Generator extends Iterator {
    next(value?: any): IteratorResult;
    throw(exception: any);
}

More info: MDN Iteration protocols

Map + Set + WeakMap + WeakSet

Efficient data structures for common algorithms. WeakMaps provides leak-free object-key’d side tables.

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references, it will not be held in the set

...

Table of Contents

Key Points

  1. run js using node as a file
  2. run js in web page on javascript console ( eg Firefox browser etc )


References

Reference_description_with_linked_URLs_______________________Notes__________________________________________________________________




https://developer.mozilla.org/en-US/docs/Web/JavaScript#for_complete_beginnersJavascript basics
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handlingControl flow and error management
https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoopEvent Loop
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promisesPromises
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_generatorsIterators and Generators





Google Javascript developer pages
https://developer.mozilla.org/en-US/docs/Web/JavaScriptMozilla Javascript developer pages
https://developers.google.com/web/fundamentals/primers/promisesJavascript promises
https://v8.dev/features/modules

JS modules

http://es5.github.io/es5 Features article

https://github.com/lukehoban/es6features#readme

http://es6-features.org/#Constants

es6 Features tester
https://2ality.com/2016/01/ecmascript-2016.htmles7 Feature summary

https://medium.com/engineered-publicis-sapient/javascript-es6-es7-es10-where-are-we-8ac044dfd964

js-versions-es10-2019-medium.com-JavaScript ES6 ES7 ES10 where are we.pdf

es8, es9, es10 overview article - Medium

https://www.w3schools.com/html/html_iframe.asp

https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies

iframes have a variety of uses to embed pages in other pages with shared access through the document model




Javascript Tools

React

Redux

Sagas
https://www.smashingmagazine.com/2018/02/javascript-firefox-debugger/

Javascript debugger for web pages in Firefox

better than js console

https://flow.org/en/Flow framework - smart type checking on js










Javascript Articles
https://medium.com/zerotomastery/web-developer-monthly-july-2019-a65ac4c1e223Web Dev blog 07/2019 - curlx   redux
https://curlx.dev/curlx basics
https://transform.tools/html-to-jsxtransform html to jsx for React
https://blog.isquaredsoftware.com/presentations/2019-06-react-redux-deep-dive/#/0redux slides - basics
https://css-tricks.com/build-a-chat-app-using-react-hooks-in-100-lines-of-code/React chat app w sockets
https://www.npmjs.com/package/socket.iosocket.io  server
https://www.npmjs.com/package/socket.io-clientsocket.io-client  client
https://blog.logrocket.com/websockets-tutorial-how-to-go-real-time-with-node-and-react-8e4693fbf843/Websockets module tutorial ( vs socket.io )


https://nextjs.org/blog/next-9Next-9 js
https://jrsinclair.com/articles/2019/what-is-a-higher-order-function-and-why-should-anyone-care/Functional Javascript
https://dev.to/sagar/three-dots---in-javascript-26ci

3 dots on parms input are rest parameters gathered automatically into an array

rest parms can be destructured into variables

spread operator expands elements of an iterable where multiple elements are used

https://developers.google.com/web/fundamentals/architecture/app-shellPWA App Shell design for fast app start, separation of content


https://medium.com/javascript-scene/what-is-webassembly-the-dawn-of-a-new-era-61256ec5a8f6

https://webassembly.org/

https://developer.mozilla.org/en-US/docs/WebAssembly

WebAssembly - a compiled binary executable using WebAssembly scripts that browsers can run alongside the js vm
WebAssembly modules will be able to call into and out of the JavaScript context and access browser functionality through the same Web APIs accessible from JavaScript







Key Concepts



Javascript Basics



Testing Node shell

open

run needed npm installs

> var stringer = require('node-csv').Stringifier;
> fs.writeFile('./msgsout.txt', JSON.stringify(msgs), (err) => { console.log(err) });
> fs.appendFile('./msgsout.txt', JSON.stringify(msgs), (err) => { console.log(err) });
> fs.appendFile('./msgsout.txt', JSON.stringify('more data 1 \n'), (err) => { console.log(err) });


Data Types


Data Types can be converted

https://gomakethings.com/converting-strings-to-numbers-with-vanilla-javascript/

> var a = "12";
> var b = "44";
> var c = Number(a) + Number(b)
> console.log(`var c = ${c}`);
var c = 56

methods to convert strings to numbers

parseInt 

parseFloat 

Number


Promises

https://developers.google.com/web/fundamentals/primers/promises


At their most basic, promises are a bit like event listeners except:

  • A promise can only succeed or fail once. It cannot succeed or fail twice, neither can it switch from success to failure or vice versa.
  • If a promise has succeeded or failed and you later add a success/failure callback, the correct callback will be called, even though the event took place earlier.

This is extremely useful for async success/failure, because you're less interested in the exact time something became available, and more interested in reacting to the outcome.

A promise can be:

  • fulfilled - The action relating to the promise succeeded
  • rejected - The action relating to the promise failed
  • pending - Hasn't fulfilled or rejected yet
  • settled - Has fulfilled or rejected

The spec also uses the term thenable to describe an object that is promise-like, in that it has a then method


Promise example

You can transform values simply by returning the new value:

var promise = new Promise(function(resolve, reject) {
  resolve
(1);
});

promise
.then(function(val) {
  console
.log(val); // 1
 
return val + 2;
}).then(function(val) {
  console
.log(val); // 3
})


Simplifying Promise sequences

https://developers.google.com/web/fundamentals/primers/promises

The response is JSON, but we're currently receiving it as plain text. We could alter our get function to use the JSON responseType, but we could also solve it in promises land:

get('story.json').then(function(response) {
 
return JSON.parse(response);
}).then(function(response) {
  console
.log("Yey JSON!", response);
})

Since JSON.parse() takes a single argument and returns a transformed value, we can make a shortcut:

get('story.json').then(JSON.parse).then(function(response) {
  console
.log("Yey JSON!", response);
})

In fact, we could make a getJSON() function really easily:

function getJSON(url) {
 
return get(url).then(JSON.parse);
}

getJSON() still returns a promise, one that fetches a url then parses the response as JSON.


How Promises work in sequence with then


You can also chain thens to run async actions in sequence.

When you return something from a then() callback, it's a bit magic. If you return a value, the next then() is called with that value. However, if you return something promise-like, the next then() waits on it, and is only called when that promise settles (succeeds/fails). For example:

getJSON('story.json').then(function(story) {
 
return getJSON(story.chapterUrls[0]);
}).then(function(chapter1) {
  console
.log("Got chapter 1!", chapter1);
})

Here we make an async request to story.json, which gives us a set of URLs to request, then we request the first of those. This is when promises really start to stand out from simple callback patterns.

You could even make a shortcut method to get chapters:

var storyPromise;

function getChapter(i) {
  storyPromise
= storyPromise || getJSON('story.json');

 
return storyPromise.then(function(story) {
   
return getJSON(story.chapterUrls[i]);
 
})
}

// and using it is simple:
getChapter
(0).then(function(chapter) {
  console
.log(chapter);
 
return getChapter(1);
}).then(function(chapter) {
  console
.log(chapter);
})

We don't download story.json until getChapter is called, but the next time(s) getChapter is called we reuse the story promise, so story.json is only fetched once. Yay Promises!


Prior to promises, we registered callbacks for events

var img1 = document.querySelector('.img-1');

function loaded() {
 
// woo yey image loaded
}

if (img1.complete) {
  loaded
();
}
else {
  img1
.addEventListener('load', loaded);
}

img1
.addEventListener('error', function() {
 
// argh everything's broken
});

This doesn't catch images that error'd before we got a chance to listen for them; unfortunately the DOM doesn't give us a way to do that. Also, this is loading one image, things get even more complex if we want to know when a set of images have loaded.





JS Modules - export and import system for reusable modules

https://v8.dev/features/modules

Export something to external clients

Within a module, you can use the export keyword to export just about anything. You can export a const, a function, or any other variable binding or declaration. Just prefix the variable statement or declaration with export and you’re all set:

// 📁 lib.mjs
export const repeat = (string) => `${string} ${string}`;
export function shout(string) {
return `${string.toUpperCase()}!`;
}


Import something to a client

You can then use the import keyword to import the module from another module. Here, we’re importing the repeat and shout functionality from the lib module, and using it in our main module:

// 📁 main.mjs
import {repeat, shout} from './lib.mjs';
repeat('hello');
// → 'hello hello'
shout('Modules in action');
// → 'MODULES IN ACTION!'


Module concepts


  • Modules have a lexical top-level scope. This means that for example, running var foo = 42; within a module does not create a global variable named foo, accessible through window.foo in a browser, although that would be the case in a classic script.

  • Similarly, the this within modules does not refer to the global this, and instead is undefined. (Use globalThis if you need access to the global this.)

  • The new static import and export syntax is only available within modules — it doesn’t work in classic scripts.



Using JS modules in a browser

On the web, you can tell browsers to treat a <script> element as a module by setting the type attribute to module.

<script type="module" src="main.mjs"></script>
<script nomodule src="fallback.js"></script>

Browsers that understand type="module" ignore scripts with a nomodule attribute. This means you can serve a module-based payload to module-supporting browsers while providing a fallback to other browsers.


Dynamic import

only load module when called. Loaded module will be cached in browser session.

<script type="module">
(async () => {
const moduleSpecifier = './lib.mjs';
const {repeat, shout} = await import(moduleSpecifier);
repeat('hello');
// → 'hello hello'
shout('Dynamic import in action');
// → 'DYNAMIC IMPORT IN ACTION!'
})();
</script>

import.meta - get metadata on a module

Another new module-related feature is import.meta, which gives you metadata about the current module. The exact metadata you get is not specified as part of ECMAScript; it depends on the host environment. In a browser, you might get different metadata than in Node.js, for example.



Javascript Async Functions

https://developers.google.com/web/fundamentals/primers/async-functions

Async functions work like this:

async function myFirstAsyncFunction() {
 
try {
   
const fulfilledValue = await promise;
 
}
 
catch (rejectedValue) {
   
// …
 
}
}

If you use the async keyword before a function definition, you can then use await within the function. When you await a promise, the function is paused in a non-blocking way until the promise settles. If the promise fulfills, you get the value back. If the promise rejects, the rejected value is thrown.


Async functions vs Promises - which reads easier?

Say we wanted to fetch a URL and log the response as text. Here's how it looks using promises:

function logFetch(url) {
 
return fetch(url)
   
.then(response => response.text())
   
.then(text => {
      console
.log(text);
   
}).catch(err => {
      console
.error('fetch failed', err);
   
});
}

And here's the same thing using async functions:

async function logFetch(url) {
 
try {
   
const response = await fetch(url);
    console
.log(await response.text());
 
}
 
catch (err) {
    console
.log('fetch failed', err);
 
}
}



Default + Rest + Spread

Callee-evaluated default parameter values. Turn an array into consecutive arguments in a function call. Bind trailing parameters to an array. Rest replaces the need for arguments and addresses common cases more directly.

function f(x, y=12) {
  // y is 12 if not passed (or passed as undefined)
  return x + y;
}
f(3) == 15
function f(x, ...y) {
  // y is an Array
  return x * y.length;
}
f(3, "hello", true) == 6
function f(x, y, z) {
  return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6

More MDN info: Default parameters, Rest parameters, Spread Operator



Generators

Generators simplify iterator-authoring using function* and yield. A function declared as function* returns a Generator instance. Generators are subtypes of iterators which include additional next and throw. These enable values to flow back into the generator, so yield is an expression form which returns a value (or throws).

Note: Can also be used to enable ‘await’-like async programming, see also ES7 await proposal.

var fibonacci = {
  [Symbol.iterator]: function*() {
    var pre = 0, cur = 1;
    for (;;) {
      var temp = pre;
      pre = cur;
      cur += temp;
      yield cur;
    }
  }
}

for (var n of fibonacci) {
  // truncate the sequence at 1000
  if (n > 1000)
    break;
  console.log(n);
}

The generator interface is (using TypeScript type syntax for exposition only):

interface Generator extends Iterator {
    next(value?: any): IteratorResult;
    throw(exception: any);
}

More info: MDN Iteration protocols



Map + Set + WeakMap + WeakSet

Efficient data structures for common algorithms. WeakMaps provides leak-free object-key’d side tables.

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references, it will not be held in the set

More MDN info: Map, Set, WeakMap, WeakSet



Proxy handlers for Object methods

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Meta_programming

const handler2 = {
get(target, name) {
console.log( `target.name = ${target} ${name}`)
return name in target ? target[name] : 44;
},
};

const p2 = new Proxy({}, handler2);
p2.a = 1;
console.log(p2.a, p2.b); // 1, 44
VM194:3 target.name = [object Object] a
VM194:3 target.name = [object Object] b
VM194:10 1 44


The Proxy.revocable() method is used to create a revocable Proxy object. This means that the proxy can be revoked via the function revoke and switches the proxy off.

Reflect - reflection in js 

Reflect is a built-in object that provides methods for interceptable JavaScript operations. The methods are the same as those of the proxy handlers.

Reflect is not a function object.

Reflect helps with forwarding default operations from the handler to the target.

With Reflect.has() for example, you get the in operator as a function:

Reflect.has(Object, 'assign') // true

Before Reflect, you typically use the Function.prototype.apply() method to call a function with a given this value and arguments provided as an array (or an array-like object).

Function.prototype.apply.call(Math.floor, undefined, [1.75])

With Reflect.apply this becomes less verbose and easier to understand:

Reflect.apply(Math.floor, undefined, [1.75])
// 1

Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111])
// "hello"

Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index
// 4

Chrome Javascript Web App Basics

...