JavaScript Notes
Primitive Datatypes
in stack
string, number, boolean, null, undefined, Symbol(ES6)
//string
"hello world"
//number
4
9.3
-10
//boolean
true
false
// null and undefined
null
undefined
primitive values are immutable.
What we see is that for mutable values, updating state applies across all references to that variable. So changing a value in one place, changes it for all references to that object. For the immutable data types, we have no way of changing the internal state of the data, so the reference always gets reassigned to a new object. The biggest implication of this is that for immutable data, equality is more reliable since we know that a value’s state won’t be changed out from under us.
String
//Single or Double quotes OK
"hello world"
'hello world'
//Concatenation
"charlie" + "brown" //"charliebrown"
//Escape Characters start with "\"
"Singin \"Do wah diddy, diddy, dum diddy do\" "
"This is a backslash: \\"
//Strings have a length property
"hello world".length //11
//Access individual characters using [] and an index
"hello"[0] //"h"
"hello"[4] //"o"
// ES6 new way of concatenation
`${variable1} and ${variable2}`
Var
JS variable name should be in camel-case.
Dynamically typed languages infer variable types at runtime.
All var statements hoisted to top of scope. If declared inside a function, the scope is inside the function.
Null and Undefined
//Variables that are declared but not
//initialized are undefined
//The following variables are undefined:
var name;
var age;
//null is "explicitly nothing"
var currentPlayer = "charlie";
currentPlayer = null; //game over
typeof null == 'object'
Built-in Method
// alert for pop up the message to the user
alert();
// prompt for user input
var name = prompt("what is your name?");
// console.log for print message on the console
console.log();
Connect HTML and JS
<script src="code.js"></script>
Equality Operators
- "==" performs type coercion: Equal to
- "===" Equal value and type
var y = null;
y == undefined //true
y === undefined //false
true == "1" //true
0 == false //true
null == undefined //true
NaN == NaN //false
Truthy and Falsy Values
Launguage classifies values as either truthy or falsy.
Falsy values
false, 0, "", null, undefined, NaN
Truthy: everything else
Function
function functionName(){
}
// function name is the reference to the function (function references)
functionName;
// run the function
functionName();
- function definitions are hoisted
- can be called with variable arguments
-
function load(){ var var0 = arguments[0]; var var1 = arguments[1]; }
-
- all functions return a value (default is undefined)
functions can have properties too:
function plus1(value) {
plus1.invocations++;
return value + 1;
}
function.bind()
the bind()
method creates a new function that, when called, has its this
keyword (inside the function) set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
Bind creates a new function that will have this
set to the first parameter passed to bind()
.
x = 9;
var module = {
x: 81,
getX: function () {
return this.x;
}
};
module.getX(); // 81
var getX = module.getX;
getX(); // 9, because in this case, "this" refers to the global object
// create a new function with 'this' bound to module
var boundGetX = getX.bind(module);
boundGetX(); // 81
ECMAScript 2015 adds support for =>
functions. =>
functions are more compact and do not change the this
pointer from their defining scope, so you may not need to use bind()
as often.
arguments
function area(length, width) {
console.log(length * width);
}
Function Declaration and a Function Expression.
whether or not you can overwrite both types of functions.
The answer is yes, no matter how you name a function, be it with a variable in a function expression or directly in a function declaration, it can be overwritten if you assign that same variable to something else, later in your code.
Use arguments keyword can get an array of arguments.
Function Declaration and Function Expression
- A Function Declaration defines a named function variable without requiring variable assignment.
- The function name is visible within it’s scope and the scope of it’s parent (which is good because otherwise it would be unreachable)
- A Function Expression defines a function as a part of a larger expression syntax (typically a variable assignment ).
- Functions defined via Functions Expressions can be named or anonymous.
- Function Expressions must not start with “function” (hence the parentheses around the self invoking example below)
//function declaration
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
//function expression anonymous
var capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
//function expression named
var capitalize = function solution(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
//self invoking function expression
(function sayHello() {
alert("hello!");
})();
Function declarations and function variables are always moved (‘hoisted’) to the top of their JavaScript scope by the JavaScript interpreter
Function expression is a better choice.
Arrow function in ES6
An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this
, arguments
, super
, or new.target
keywords.
const name = (a,b) =>{
}
name(a,b)
An arrow function does not have its own this
. The this
value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this
which is not present in current scope, an arrow function ends up finding the this
from its enclosing scope.
Scope
- Scope is the context that code is executed in.
- Two scopes:
- Global scope
- function scope
- all var statements hoisted to top of scope
In ES6, non-hoisting let and const with explicit scopes. Avoid use Var.
- let: use block scope: anything within the {}
- const: cannot change content through =
Higher Order Functions
either take function as arguments or return another function
- to do this pass the function name only as the argument.
- or use anonymous funtion to achieve this ( ) => { }
A callback function is a function passed into another function as an argument, is to be executed after another function has finished executing — hence the name ‘call back’.
callback function does not block the code excution.
Reference types(objects/arrays)
in heap
Object
Store data in key-value pairs called properties, unordered, inside { }.
the person variable stores the pointer to the object.
so if a const variable, can edit the content by person.name = "hehe". no error because the pointer person is not chaned.
var person = {
name: "Travis",
age: 21,
city: "LA"
};
- key can be any string
- var x = { "":"empty","---":"dashes"}
- enumerate use Object.keys()
- Object.keys({name: "alice", age: 23}) = ["name","age"]
Retrieving Data:
- bracket: person["name"]
- dot notation: person.name
//you cannot use dot notation if the property starts with a number
someObject.1blah //INVALID
someObject["1blah"] //VALID!
//you can lookup using a variable with bracket notation
var str = "name";
someObject.str //doesn't look for "name"
someObject[str] //does evaluate str and looks for "name"
//you cannot use dot notation for property names with spaces
someObject.fav color //INVALID
someObject["fav color"]; //VALID
Updating Data
access a property and reassign it
Creating Objects
//make an empty object and then add to it
var person = {}
//all at once
var person = {
name: "Travis",
age: 21,
city: "LA"
};
//another way of initializing an Object
var person = new Object();
person.name = "Travis";
person.age = 21;
person.city = "LA";
Copy the object
- Object.assign({}, object_name)
- {...object_name}
Array
special type of object in [ ], array elements can be undefined
//We can initialize an empty array two ways:
var friends = [];
var friends = new Array();
//Arrays can hold any type of data
var random_collection = [49, true, "Hermione", null];
//Arrays have a length property
var nums = [45,37,89,24];
nums.length //4
//The some() method executes the callback function once for each element present in the array until it finds the one where callback returns a truthy value (a value that becomes true when converted to a Boolean).
array.some((var)=>{
return var.equals();
});
- push/pop: end of an array, pop return the removed element
- unshift/shift: front of an array, unshift to add, shift to remove and return the removed element
- indexOf: find the index of an item in an array.
- slice: copy parts of an array. [ start, end), if .slice(), the whole array is copied.
- splice: to remove, specify the start index and number of elements to be removed. .splice(1,3)
- spread: In ES6, [...array] pull all elements of the old array out, add them to the new array [].
- map: transform an array, return a new array. take in a function to determine how to transform each element.
Default parameters
// explicitly define default values if parameter is not defined
function myFunc(a=1, b="hello"){
}
Rest and Spread parameters ...
//A function's last parameter can be prefixed with ... which will cause all remaining
//(user supplied) arguments to be placed within a "standard" javascript array. Only the
//last parameter can be a "rest parameter".
function myFunc (a,b,...theArgsArray){
var c = theArgsArray[0];
}
// Spread syntax allows an iterable such as an array expression or string to be expanded
// in places where zero or more arguments (for function calls) or elements (for array
// literals) are expected, or an object expression to be expanded in places where zero
// or more key-value pairs (for object literals) are expected.
[...array]
{...object}
Destructring
// old way
var a = arr[0];
var b = arr[1];
var c = arr[2];
var name = obj.name;
var age = obj.age;
var salary = obj.salary;
function render(props){
var name = props.name;
var age = props.age;
}
// new way
let[a,b,c] = arr;
let{name,age,salary} = obj;
function render({name,age}){
Template Literals
// old way
var str = "Hi" + name + " your age is " + age;
// new way and allows multi-line strings
var str = `Hi ${name} your age is ${age}`;
For of
// iterate over arrays, strings, Map, Set without using indexes
for(let ent of a) {
}
Dates
var date = new Date();
- date.valueOf() = 1452359316314
- date.toISOString() = '2016-01-09T17:08:36.314Z'
- date.toLocaleString() = '1/9/2016, 9:08:36 AM'
Regular Expressions
var re = /ab+c/;
var re = new RegExp('ab+c');
search/test
/HALT/.test(str) //returns true if string str has the substr HALT
'xxxxxx'.search
exec/match/replace
var str = "this has 'quoted' words like 'this'";
var re = /'[^']*'/g;
re.exec(str) //returns["'quoted'",index:9, input:...]
str.match(re) //returns ["'quoted'","'this'"]
str.replace(re,'xxx');
Get javascript into a web page
<script type="text/javascript" src="code.js"></script>
forEach
JavaScript provides an easy built-in way of iterating over an array.
arr.forEach(someFunctionName)
var colors = ["red", "orange","yellow", "green"];
colors.forEach(function(color){
//color is a placeholder, call it whatever you want
console.log(color);
});
Asynchronous Code
does not execute immediately.
setTimeout(()=>{
console.log('Timer is done!');
},2000};
callback function here, js immediately move to the next line of code (excute synchronous code), then excute asynchronous code once its done.
Promise
A promise is an object representing the eventual completion or failure of an asynchronous operation.
A promise is a returned object to which you attach callbacks, instead of passing callbacks into a function.
const fetchData = ()=>{
const promise = new Promise((resolve,reject)=>{
setTimout(()=>{
resolve('Done!');
},2000);
});
return promise;
};
fetchData()
.then(text=>{
console.log(text);
return fetchData();
})
.then();
OOP
Methods
function as property in an object.
var obj = {count:0}
obj.increment = function(amount){
this.count += amount;
return this.count;
}
// usage
obj.increment(1);
shorter way
var obj = {
increment() {
/* code */
}
};
This
can be determined using four rules( global, object/implicit, explicit, new )
- global context
- this refer to the global object: window object
- can use this to create a global variable
- strict mode: "use strict", this will be undefined. not creating any global variable
- Implicit/ object
- 'this' is inside of a declared object, the value of 'this' will be the closest parent object.
- In methods, this will be bound to the object.
- explicit binding
- choose what we want the context of 'this' to be using call, apply or bind, and can only be used by functions.
- use the following methods to set 'this' to another object
- call, thisArg,a,b,c,d,.... invoke immediately
- apply, thisArg, [a,b,c,d,...] invoke immediately
- bind, thisArg,a,b,c,d,.... not invoke immediately
- bind returns a function definition with 'this' set to the value thisArg. don't need to know all the arguments up front.
- new
- a new object is created. new keyword used with the function, 'this' refers to the new object created.
Classes
functions are classes in JS. Classes are in fact "special functions"
// Class declarations
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
//method
calcArea() {
return this.height * this.width;
}
}
// Class expressions
// Class expressions can be named or unnamed. The name given to a named class expression is local to the class's body.
// unnamed
let Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name);
// output: "Rectangle"
// named
let Rectangle = class Rectangle2 {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name);
// output: "Rectangle2"
class declarations are not hoisted.
old style constructor
- start with captialized function name
- keyword 'this' is back, we would like 'this' to refer to the object we will create from our constructor function.
new keyward
- creates an empty object
- sets the keyword 'this' to be that empty object
- add the line `return this` to the end of the function, which follows it
- add a property onto the empty object called "__proto__" which links the prototype property on the constructor function to the empty object
multiple constructor
- call or apply to avoid duplications
Prototypes
JS has the notion of a prototype object for each object instance.
the prototype is shared among all objects created by that constructor function.
To share properties and methods for objects created by a constructor function, place them in the prototype as it is the most efficient.
prototype chain
The JavaScript prototype
property allows you to add new properties/new methods to object constructors:
function Person(first, last, age, eyecolor) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";
Person.prototype.name = function() {
return this.firstName + " " + this.lastName;
};
Inheritance
All JavaScript objects inherit properties and methods from a prototype.
prototype-based inheritance: single inheritance support
Rectangle.prototype = new Shape();
In ES6
class Rectangle extends Shape {
constructor(height,width){
// If there is a constructor present in the subclass, it needs to first call super() before using "this".
super(height,width);
this.height = height;
this.width = width;
}
// Method
area(){
}
}
Note that classes cannot extend regular (non-constructible) objects. If you want to inherit from a regular object, you can instead use Object.setPrototypeOf()
:
const Animal = {
speak() {
console.log(`${this.name} makes a noise.`);
}
};
class Dog {
constructor(name) {
this.name = name;
}
}
// If you do not do this you will get a TypeError when you invoke speak
Object.setPrototypeOf(Dog.prototype, Animal);
let d = new Dog('Mitzie');
d.speak(); // Mitzie makes a noise.
Functional programming
newArr = anArr.map((val,ind) => val*ind);
can wirite entire program as functions with no side-effects
anArr.filter(filterFunc).map(mapFunc).reduce(func)
Closure
closure is a inner function that makes use of variables defined in outer functions that have returned.
使用闭包会使函数中变量都保存在内存中
Closure is used to create private variables
module.exports = whatever needed to be exported
exports files
to import the file, use require