Primitive types:
Reference types:
- Object: var x = {firstName:"John", lastName:"Doe"}; // Object
Function Expression: var x = function() {};
/* Function declaration */
function foo() {
console.log('bar');
}
/* Function expression */
var baz = function() {
console.log('bar2');
};
Data types
var x = "Abc" + 16 + 4; //=> Abc164
var x = 16 + 4 + "Abc"; //=> 20Abc
Complex types
The typeof operator can return one of two complex types:
Notes:
null === undefined // false
null == undefined // true
For examples
typeof undefined // Returns "undefined"
typeof {name:'John', age:34} // Returns "object"
typeof [1,2,3,4] // Returns "object" (not "array", see note below)
typeof null // Returns "object"
typeof function myFunc(){} // Returns "function"
JavaScript basic functions
var person = {
firstName:"John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var myObject = {
firstName:"Mary",
lastName: "Doe",
}
person.fullName.call(myObject); // Will return "Mary Doe"
var person = {
firstName:"John",
lastName: "Doe",
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var myObject = {
firstName:"Mary",
lastName: "Doe",
}
person.fullName.apply(myObject); // Will return "Mary Doe"
The difference between call() and apply()
The only difference is:
call() takes any function arguments separately.
apply() takes any function arguments as an array.
Example of using apply with array
Math.max(1,2,3); // Will return 3
Math.max.apply(null,[1,2,3]); // Will also return 3
When to use call(), apply(), bind()
Function.prototype.bind = function(ctx) {
var fn = this;
return function() {
fn.apply(ctx, arguments);
};
};
Use .bind() when you want that function to later be called with a certain context, useful in events.
Use .call() or .apply() when you want to invoke the function immediately, and modify the context.
Call/apply call the function immediately, whereas bind returns a function that, when later executed, will have the correct context set for calling the original function. This way you can maintain context in async callbacks and events.
JavaScript Closure
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
// the counter is now 3
A closure is a function having access to the parent scope, even after the parent function has closed.
//console.log(count); //=> "Uncaught ReferenceError: count is not defined"
console.log(closureFunction()); //=> 1
console.log(closureFunction()); //=> 2
console.log(closureFunction()); //=> 3
console.log(typeof closureFunction); //=> "function"
console.log(closureFunction); //=> "ƒ () { return count += 1; }"
Javascript advanced functions
For example, (() => 0)() is an expression
For example, (() => (1 + 1, 2 + 2))() //=> 4
(() => (
1 + 1,
2 + 2
))() //=> 4
An expression is a JavaScript statement
For example, (() => {})() //=> undefined
(() => {
1 + 1;
2 + 2
})() //=> undefined
((diameter) => diameter * 3.14159265)(1 + 1)
//=> 6.2831853
((diameter) => diameter * 3.14159265)(2,1)
//=> 6.2831853
((diameter) => diameter * 3.14159265)(1,2)
//=> 3.14159265
((x) => (y) => x)(1)(2)
//=> 1
((x) => (y) => x)(1)
//=> Function
((diameter) => diameter * 3.14159265)(2)
//=> 6.2831853
((PI) =>
(diameter) => diameter * PI
)(3.14159265)(2)
//=> 6.2831853
((diameter) =>
((PI) =>
diameter * PI)(3.14159265))(2)
//=> 6.2831853
((diameter) => {
const PI = 3.14159265;
return diameter * PI
})(2)
//=> 6.2831853
const: Chú ý dấu "`" sử dụng với dấu "$"
const repeat = (num, fn) =>
(num > 0)
? (repeat(num - 1, fn), fn(num))
: undefined
repeat(3, function (n) {
console.log(`Hello ${n}`)
})
arguments:
const args = function (a, b) {
return arguments;
}
args(2,3)
//=> { '0': 2, '1': 3 }
arguments:
const plus = function () {
return arguments[0] + arguments[1];
}
plus(2,3)
//=> 5
arguments:
const howMany = function () {
return arguments['length'];
}
howMany()
//=> 0
howMany('hello')
//=> 1
howMany('sharks', 'are', 'apex', 'predators')
//=> 4
arguments:
(function () {
return (function () { return arguments[0]; })('inner');
})('outer')
//=> "inner"
(function () {
return (() => arguments[0])('inner');
})('outer')
//=> "outer"
mapWith
const mapWith = (fn) =>
(array) => map(array, fn);
----------------------------------------
const row = function () {
return mapWith(
(column) => column * arguments[0],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
)
}
row(3)
//=> [3,6,9,12,15,18,21,24,27,30,33,36]
----------------------------------------
const row = function () {
return mapWith(
function (column) { return column * arguments[0] },
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
)
}
row(3)
//=> [1,4,9,16,25,36,49,64,81,100,121,144]
Objects use [] to access the values by name, using a string:
{ year: 2012, month: 6, day: 14 }['day']
//=> 14
{ 'first name': 'reginald', 'last name': 'lewis' }['first name']
//=> 'reginald'
const date = { year: 2012, month: 6, day: 14 };
date['day'] === date.day
//=> true