SlideShare a Scribd company logo
Practical JavaScript Programming
Session 3
Wilson Su
2
https://www.slideshare.net/sweekson/
Outline
3
Practical JavaScript Programming
Chapter 5.
● Function Definitions
● Function Parameters
● The Arguments Object
● What is ‘this’?
● Function Invocation
● Closures
Functions
Chapter 6.
Constructors And Prototypes
● Constructors
● Prototypes
● Inheritance
● Class
4
Wilson Su
Front-end Developer, HIE
● 6 years in web design
● Specialize in JavaScript /
CSS / HTML / OOP / Git
● Familiar with PHP / Design
Pattern
● Interested in UI & Ix Design
wilson_su@trend.com.tw
Auxiliary Materials
5
Parentheses
6
1. 5.toString(); // SyntaxError
2. (5).toString(); // '5'
3.
4. var good = { grade: 'A' }, bad = { grade: 'F' };
5. var score = 75;
6.
7. if (score > 60) {
8. good.grade; // 'A'
9. } else {
10. bad.grade;
11. }
12.
13. (score > 60 ? good : bad).grade; // 'A'
Chapter 5.
Functions
7
In JavaScript, functions are
first-class objects.
8
Function Definitions
9
3 Ways To Define A Function
10
1. /* Function declarations */
2. function name ([param[, param[..., param]]]) {
3. [statements]
4. }
5.
6. /* Function expressions */
7. var name = function [name] ([param[, param[..., param]]]) {
8. [statements]
9. }
10.
11. /* Function Constructor */
12. var name = new Function([param[, param[..., param]],] body);
Function Declarations
11
1. function echo (value) { return value; }
2. typeof echo; // 'function'
3. echo.name; // 'echo'
4. echo.length; // 1
5. echo('ABC'); // 'ABC'
6.
7. function () {} // SyntaxError
Function Expressions
12
1. var multiply = function (x, y) {
2. return x * y;
3. };
4.
5. typeof multiply; // 'function'
6. multiply.name; // 'multiply'
7. multiply.length; // 2
8. multiply(2, 3); // 6
9.
10. (function (value) { return value; })
11. // function (value) { return value; }
Named Function Expressions
13
1. var calcalate = function calc (v1, v2) {
2. console.log(typeof calc); // 'function'
3. console.log(calcalate === calc); // true
4. return v1 + v2;
5. }
6.
7. typeof calcalate; // 'function'
8. calcalate.name; // 'calc'
9. calcalate.length; // 2
10. calcalate(2, 3); // 5
11. calc; // ?
1. var calcalate = function calc (v1, v2) {
2. console.log(typeof calc); // 'function'
3. console.log(calcalate === calc); // true
4. return v1 + v2;
5. }
6.
7. typeof calcalate; // 'function'
8. calcalate.name; // 'calc'
9. calcalate.length; // 2
10. calcalate(2, 3); // 5
11. calc; // ReferenceError
The Function() Constructor
14
1. var subtract = new Function('x', 'y', 'return x - y');
2.
3. typeof subtract; // 'function'
4. subtract.name; // 'anonymous'
5. subtract.length; // 2
6. subtract(18, 3); // 15
Functions created
with the Function constructor
always are created in
the global scope.
15
The Function() Constructor Create Functions In The Global Scope
16
1. var uppercaser = function (skill) {
2. return new Function('return skill.toUpperCase()');
3. };
4. var uppercase = uppercaser('html');
5. var skill = 'css';
6.
7. uppercase('js'); // ?
1. var uppercaser = function (skill) {
2. return new Function('return skill.toUpperCase()');
3. };
4. var uppercase = uppercaser('html');
5. var skill = 'css';
6.
7. uppercase('js'); // 'CSS'
Defining Object Methods
17
1. var dog = {
2. bark: function bowwow () {
3. console.log('Bowwow!');
4. }
5. };
6.
7. typeof dog.bark; // 'function'
8. dog.bark.name; // 'bowwow'
9. dog.bark.length; // 0
10. dog.bark(); // 'Bowwow!'
Defining Object Methods In A Shorter Syntax
18
1. var cat = {
2. meow () {
3. console.log('Meow~');
4. }
5. };
6.
7. typeof cat.meow; // 'function'
8. cat.meow.name; // 'meow'
9. cat.meow.length; // 0
10. cat.meow(); // 'Meow~'
Function Return
19
1. function noop () {}
2. function nothing () { return; }
3. function echo (value) { return value; }
4.
5. noop(true); // undefined
6. nothing('Hi'); // undefined
7. echo([10, 20]); // (2) [10, 20]
Function Hoisting
20
1. hello(); // 'Hello!'
2. aloha(); // ?
3.
4. function hello () {
5. return 'Hello!';
6. }
7.
8. var aloha = function () {
9. return 'Aloha!';
10. };
1. hello(); // 'Hello!'
2. aloha(); // TypeError
3.
4. function hello () {
5. return 'Hello!';
6. }
7.
8. var aloha = function () {
9. return 'Aloha!';
10. };
Nested Functions
21
1. function outer () {
2. function inner () {
3. return 'Inner';
4. }
5. return inner();
6. }
7.
8. outer(); // 'Inner';
9. inner(); // ?
1. function outer () {
2. function inner () {
3. return 'Inner';
4. }
5. return inner();
6. }
7.
8. outer(); // 'Inner';
9. inner(); // ReferenceError
Arrow Functions
22
1. var remove = (target, array) => {
2. var index = array.indexOf(target);
3. return index > -1 ? !!array.splice(index, 1) : false;
4. };
5. var concat = (list1, list2) => list1.concat(list2);
6. var numbers = [100, 200, 300];
7.
8. remove(200, numbers); // true
9. numbers; // (2) [100, 300]
10. concat(numbers, [500, 700]); // (4) [100, 300, 500, 700]
11. numbers; // ?
1. var remove = (target, array) => {
2. var index = array.indexOf(target);
3. return index > -1 ? !!array.splice(index, 1) : false;
4. };
5. var concat = (list1, list2) => list1.concat(list2);
6. var numbers = [100, 200, 300];
7.
8. remove(200, numbers); // true
9. numbers; // (2) [100, 300]
10. concat(numbers, [500, 700]); // (4) [100, 300, 500, 700]
11. numbers; // (2) [100, 300]
More Examples With Arrow Functions
23
1. var noop = () => {};
2. var book = title => ({ title });
3.
4. book('Zero to One'); // {title: 'Zero to One'}
5.
6. [{ id: 10 }, { id: 20 }, { id: 30 }].map(item => item.id);
7. // (3) [10, 20, 30]
Generator Functions
24
1. function* generator (x) {
2. yield x * 10;
3. yield x + 50;
4. }
5.
6. var iterator = generator(10);
7.
8. typeof generator; // 'function'
9. typeof iterator; // 'object'
10.
11. iterator.next(); // {value: 100, done: false}
12. iterator.next(); // {value: 60, done: false}
13. iterator.next(); // {value: undefined, done: true}
Function Parameters
25
Parameter Defaults
26
1. function add (x, y) {
2. console.log(x); // 5
3. console.log(y); // undefined
4. console.log(x + y); // NaN
5. x = x || 0;
6. y = y || 0;
7. return x + y;
8. }
9.
10. add(5); // 5
Passed By Value / Passed By Reference
27
1. function update (string, object, array) {
2. string = 'aloha';
3. object.id = 2;
4. array = [];
5. }
6.
7. var string = 'hello', object = { id: 1 }, array = [10, 20];
8.
9. update(string, object, array);
10. console.log(string); // ?
11. console.log(object); // ?
12. console.log(array); // ?
1. function update (string, object, array) {
2. string = 'aloha';
3. object.id = 2;
4. array = [];
5. }
6.
7. var string = 'hello', object = { id: 1 }, array = [10, 20];
8.
9. update(string, object, array);
10. console.log(string); // 'hello'
11. console.log(object); // ?
12. console.log(array); // ?
1. function update (string, object, array) {
2. string = 'aloha';
3. object.id = 2;
4. array = [];
5. }
6.
7. var string = 'hello', object = { id: 1 }, array = [10, 20];
8.
9. update(string, object, array);
10. console.log(string); // 'hello'
11. console.log(object); // {id: 2}
12. console.log(array); // ?
1. function update (string, object, array) {
2. string = 'aloha';
3. object.id = 2;
4. array = [];
5. }
6.
7. var string = 'hello', object = { id: 1 }, array = [10, 20];
8.
9. update(string, object, array);
10. console.log(string); // 'hello'
11. console.log(object); // {id: 2}
12. console.log(array); // (2) [10, 20]
Default And Destructured Parameters
28
1. function fn1 (x = 0) {}
2.
3. function fn2 (x = y(), z = []) {}
4.
5. function fn3 (x, y = x, z = y + 1) {}
6.
7. function fn4 ({ multiplier = 3 }, [x, y, z = 5]) {}
Rest Parameters
29
1. function join (...args) {
2. return args.join(' ');
3. }
4. function sum (...[x, y, z]) {
5. return x + y + z;
6. }
7.
8. join('Ryan', 'likes', 'JS'); // 'Ryan likes JS'
9.
10. sum(1); // NaN
11. sum(1, 2, 3); // 6
12. sum(1, 2, 3, 4); // 6
The Arguments Object
30
The arguments Object
31
1. function fn () {
2. console.log(arguments);
3. }
4.
5. fn(10, 20); // (2) [10, 20]
The arguments object is not a
real array.
32
The arguments Object
33
1. function fn () {
2. console.log(arguments.length); // 2
3. console.log(arguments[0]); // 10
4. console.log(arguments[1]); // 20
5. console.log(typeof arguments); // 'object'
6. console.log(arguments instanceof Array); // false
7. }
8.
9. fn(10, 20);
From arguments To An Array
34
1. function toArray1 () {
2. return Array.prototype.slice.call(arguments, 0);
3. }
4. function toArray2 () {
5. return [].slice.call(arguments, 0);
6. }
7.
8. toArray1(1, 2, 3); // (3) [1, 2, 3]
9. toArray1(1, 2, 3) instanceof Array; // true
10.
11. toArray2(4, 5, 6); // (3) [4, 5, 6]
12. toArray2(4, 5, 6) instanceof Array; // true
From arguments To An Array
35
1. function toArray3 () {
2. return arguments.length === 1
3. ? [arguments[0]]
4. : Array.apply(null, arguments);
5. }
6.
7. /* ES6 */
8. function toArray4 () {
9. return Array.from(arguments);
10. }
Destructuring
36
1. function fn () {
2. var args = [...arguments];
3. var [x, y, ...rest] = arguments;
4.
5. console.log(args); // (5) [10, 20, 30, 40, 50]
6. console.log(args instanceof Array); // true
7. console.log(x); // 10
8. console.log(y); // 20
9. console.log(rest); // (3) [30, 40, 50]
10. }
11.
12. fn(10, 20, 30, 40, 50);
Arrow funtions do not bind an
arguments object.
37
Arrow Funtions
38
1. var fn = () => arguments;
2. var calc = function () {
3. var fn = (multiple) => arguments[0] * multiple;
4. return fn(3);
5. };
6.
7. fn(); // ?
8. calc(8); // ?
1. var fn = () => arguments;
2. var calc = function () {
3. var fn = (multiple) => arguments[0] * multiple;
4. return fn(3);
5. };
6.
7. fn(); // ReferenceError
8. calc(8); // ?
1. var fn = () => arguments;
2. var calc = function () {
3. var fn = (multiple) => arguments[0] * multiple;
4. return fn(3);
5. };
6.
7. fn(); // ReferenceError
8. calc(8); // 24
What is ‘this’?
39
Global Context
40
1. /* In a browser */
2. this; // Window { … }
3. this === window; // true
4.
5. /* In Node */
6. this; // {}
7. this === module.exports; // true
Function Context
41
1. /* In a browser */
2. var that = function () { return this; };
3. that(); // Window { … }
4. that() === window; // true
5.
6. /* In Node */
7. var that = function () { return this; };
8. that(); // { global: …, console: … }
9. that() === global; // true
Nested Functions
42
1. var root = this;
2. function outer () {
3. function inner () { return this; }
4. var that = inner();
5.
6. console.log(that); // Window { … }
7. console.log(that === window); // true
8. console.log(that === this); // true
9. console.log(that === root); // true
10. }
11.
12. outer();
The Function Constructor
43
1. var self = new Function('return this');
2.
3. self(); // Window { … }
4. self() === window; // true
5. self() === this; // true
Object Methods
44
1. var data = {
2. self: function () {
3. return this;
4. }
5. };
6.
7. data.self(); // {self: function}
8. data.self() === data; // true
Object Methods Refer To Global Functions
45
1. function age () { return this._age; }
2.
3. var dog = { _age: 5, age: age };
4. var cat = { _age: 1, age: age };
5.
6. dog.age(); // 5
7. cat.age(); // 1
Getters And Setters
46
1. var data = {
2. x: 10,
3. get y () { return this.x + 5; },
4. set z (z) { this.x = this.x * z; }
5. };
6.
7. data.z = 3;
8.
9. console.log(data.x); // ?
10. console.log(data.y); // ?
1. var data = {
2. x: 10,
3. get y () { return this.x + 5; },
4. set z (z) { this.x = this.x * z; }
5. };
6.
7. data.z = 3;
8.
9. console.log(data.x); // 30
10. console.log(data.y); // ?
1. var data = {
2. x: 10,
3. get y () { return this.x + 5; },
4. set z (z) { this.x = this.x * z; }
5. };
6.
7. data.z = 3;
8.
9. console.log(data.x); // 30
10. console.log(data.y); // 35
Method Chaining
47
1. [2, 5, 1, 7, 4]
2. .sort(function (a, b) { return a - b })
3. .reverse()
4. .map(function (n) { return n * 10; });
5.
6. // (6) [70, 50, 40, 20, 10]
Chainable Methods
48
1. var list = {
2. items: [3, 8, 5],
3. push: function (value) {
4. this.items.push(value); return this;
5. },
6. remove: function (value) {
7. var index = this.items.indexOf(value);
8. if (index > -1) { this.items.splice(index, 1); }
9. return this;
10. }
11. };
12. list.push(7).push(2).remove(8).items;
13. // (4) [3, 5, 7, 2]
An arrow function does not
create its own this value.
49
Arrow Functions Used As Methods
50
1. var root = this;
2. var object = {
3. origin: function () { return this; },
4. short: () => this
5. };
6.
7. object.origin() === object; // true
8. object.origin() === object.short(); // false
9. object.short() === root; // true
Common Mistake With this
51
1. var zack = {
2. nickname: 'Z',
3. greet: function () {
4. console.log('Hi, I’m ' + this.nickname);
5. }
6. };
7. var greet = zack.greet;
8.
9. greet(); // ?
1. var zack = {
2. nickname: 'Z',
3. greet: function () {
4. console.log('Hi, I’m ' + this.nickname);
5. }
6. };
7. var greet = zack.greet;
8.
9. greet(); // 'Hi, I’m undefined'
Function Invocation
52
Invoking Functions
53
1. function add (x, y) {
2. return x + y;
3. }
4.
5. add(5, 8); // 13
6. Math.floor(3.14); // 3
Invoking Object Methods
54
1. var employee = {
2. title: 'PM',
3. name: 'Alex',
4. info: function () {
5. return this.name + ' is a ' + this.title;
6. }
7. };
8.
9. employee.info(); // 'Alex is a PM'
Function Call
55
1. var name = 'Window';
2. var jack = { name: 'Jack' }, nick = { name: 'Nick' };
3.
4. function whoami () { return this.name; }
5.
6. whoami(); // 'Window'
7. whoami.call(this); // 'Window'
8. whoami.call(jack); // 'Jack'
9. whoami.call(nick); // 'Nick'
10.
11. [1, 2].concat.call([3, 4], [5, 6]); // ?
1. var name = 'Window';
2. var jack = { name: 'Jack' }, nick = { name: 'Nick' };
3.
4. function whoami () { return this.name; }
5.
6. whoami(); // 'Window'
7. whoami.call(this); // 'Window'
8. whoami.call(jack); // 'Jack'
9. whoami.call(nick); // 'Nick'
10.
11. [1, 2].concat.call([3, 4], [5, 6]); // (4) [3, 4, 5, 6]
Function Apply
56
1. Math.max(5, 2, 7, 4); // 7
2. Math.max.apply(null, [9, 1, 3, 6]); // 9
3.
4. function sum () {
5. return [].slice.call(arguments, 0).reduce((a, b) => a + b);
6. }
7.
8. sum.apply(null, [1, 2, 3, 4, 5]); // 15
The function.bind() Method
57
1. function color () { return this.color; }
2.
3. var yellow = { color: '#ff3' };
4. var purple = { color: '#609' };
5.
6. typeof color.bind(yellow); // 'function'
7. color.bind(yellow)(); // '#ff3'
8.
9. typeof color.bind(purple); // 'function'
10. color.bind(purple)(); // '#609'
Currying
58
1. function add (x, y) {
2. return x + y;
3. }
4.
5. var add5 = add.bind(null, 5); // Curried
6.
7. add(5, 3); // 8
8.
9. add5(10); // ?
10. add5(60); // ?
1. function add (x, y) {
2. return x + y;
3. }
4.
5. var add5 = add.bind(null, 5); // Curried
6.
7. add(5, 3); // 8
8.
9. add5(10); // 15
10. add5(60); // ?
1. function add (x, y) {
2. return x + y;
3. }
4.
5. var add5 = add.bind(null, 5); // Curried
6.
7. add(5, 3); // 8
8.
9. add5(10); // 15
10. add5(60); // 65
Self-Invoking Functions (Immediately Invoked Function Expression)
59
1. var number = (function (x) { return x + 3; })(7);
2. console.log(number); // 10
3.
4. (() => 'blabla')(); // 'blabla'
5.
6. (function (_) {
7. var title = 'My Home';
8. console.log(window.title); // undefined
9. })(underscore);
Closures
60
A closure is the combination of
a function and the lexical
environment within which that
function was declared.
61
Lexical Scope / Static Scope
62
1. function outer () {
2. var skill = 'JavaScript';
3. function inner () {
4. console.log(skill); // 'JavaScript'
5. }
6. inner();
7. console.log(title); // 'Tutorial'
8. }
9. var title = 'Tutorial';
10.
11. outer();
inner()
outer()
global
console.log(skill);
console.log(title);
(NONE)
skill = 'JavaScript'
title = 'Tutorial'
Scope Chain
63
Closures
ScopeChain
Reference to outer lexical enviroment
Closures
64
1. function doubler (n) { return function () { return n * 2; }; }
2. function subtractor (x) { return (y) => (x = x - y); };
3.
4. var sixteen = doubler(8);
5. var subtract = subtractor(100);
6.
7. sixteen(); // 16
8.
9. subtract(15); // ?
10. subtract(20); // ?
1. function doubler (n) { return function () { return n * 2; }; }
2. function subtractor (x) { return (y) => (x = x - y); };
3.
4. var sixteen = doubler(8);
5. var subtract = subtractor(100);
6.
7. sixteen(); // 16
8.
9. subtract(15); // 85
10. subtract(20); // ?
1. function doubler (n) { return function () { return n * 2; }; }
2. function subtractor (x) { return (y) => (x = x - y); };
3.
4. var sixteen = doubler(8);
5. var subtract = subtractor(100);
6.
7. sixteen(); // 16
8.
9. subtract(15); // 85
10. subtract(20); // 65
1. function doubler (n) {
2. return function () {
3. return n * 2;
4. };
5. }
6. var sixteen = doubler(8);
65
Closure
The instance sixteen maintains a reference to its lexical environment,
within which the variable n exists.
Using Closure To Define Private Properties
66
1. function Circle (radius) {
2. this.getRadius = function () { return radius; };
3. this.setRadius = function (value) { radius = value; };
4. }
5. var circle = new Circle(10);
6.
7. circle.radius; // undefined
8. circle.getRadius(); // 10
9. circle.setRadius(20); // 20
10. circle.getRadius(); // 20
A Common Mistake With Closure
67
1. var i = 0, fn = {};
2.
3. for (; i < 5; ++i) {
4. fn['get' + i] = function () {
5. console.log(i);
6. };
7. }
8.
9. fn.get2(); // ?
1. var i = 0, fn = {};
2.
3. for (; i < 5; ++i) {
4. fn['get' + i] = function () {
5. console.log(i);
6. };
7. }
8.
9. fn.get2(); // 5
Chapter 6.
Constructors And Prototypes
68
Constructors
69
Constructors
70
1. function Fruit (name) {
2. this.name = name;
3. }
4.
5. var kiwi = new Fruit('Kiwi');
6.
7. kiwi.name; // 'Kiwi'
Arrow functions cannot
be used as constructors.
71
Arrow Functions Cannot Be Used As Constructors
72
1. var Cloth = (type) => {
2. this.type = type;
3. };
4.
5. new Cloth('Shirt'); // TypeError
Prototypes
73
Prototype-based Programming
Prototype-based programming is a style of object-oriented programming in
which behaviour reuse is performed via a process of reusing existing
objects via delegation that serve as prototypes. – Wiki
74
Prototypes
The Special Object Properties
75
● object.prototype returns a reference to the prototype for a class of
objects.
● object.__proto__ returns a reference to the internal prototype of the
specified object.
Prototypes
The Prototype Chain Of An Instance
76
1. function Fruit (name) {
2. this.name = name;
3. }
4.
5. var kiwi = new Fruit();
6.
7. kiwi.__proto__ === Fruit.prototype; // true
8. kiwi.__proto__.__proto__ === Object.prototype; // true
9. kiwi.__proto__.__proto__.__proto__; // * null
10.
11. kiwi.__proto__ === Object.getPrototypeOf(kiwi); // true
77
var kiwi = new Object();
kiwi.__proto__ = Fruit.prototype;
Fruit.call(kiwi);
1
2
3
What Does The new Operator Do?
Prototypes
var kiwi = new Fruit();
⇒
return kiwi;4
The Prototype Chain Of A Constructor
78
1. function Dog () {}
2. Dog.prototype.self = function () { return this; };
3.
4. var dog = new Dog();
5.
6. Dog.__proto__ === Function.prototype; // true
7. Dog.__proto__.__proto__ === Object.prototype; // true
8. Dog.__proto__.__proto__.__proto__; // * null
9.
10. Dog.prototype.constructor === Dog; // true
11. dog.constructor === Dog; // true
FunctionsInstances Prototypes
d1
function Function () {}
function Object () {}
function Dog () {}
Function.prototype
Object.prototype
Dog.prototype
var … = new Dog();
d2
o1
var … = new Object();
o2
__proto__
prototype
constructor
null
Creating Objects Using Object.create()
80
1. var animal = { gender: 'Unknown' };
2. var human = Object.create(animal);
3. var female = Object.create(human, {
4. gender: { value: 'Female' }
5. });
6.
7. human.gender; // 'Unknown'
8. human.__proto__ === animal; // true
9.
10. female.gender; // 'Female'
11. female.__proto__ === human; // true
12. female.__proto__.__proto__ === animal; // true
Creating Objects Using Object.create(null)
81
1. var common = {};
2. var uncommon = Object.create(null);
3.
4. common.constructor === Object; // true
5. common.__proto__ === Object.prototype; // true
6.
7. uncommon.constructor; // undefined
8. uncommon.__proto__; // undefined
You can add properties and
methods to the prototype of
built-in objects.
82
Adding Methods To Array.prototype
83
1. Array.prototype.first = function () {
2. return this[0];
3. };
4.
5. Array.prototype.last = function () {
6. return this[this.length - 1];
7. };
8.
9. var numbers = [100, 200, 300];
10.
11. numbers.first(); // 100
12. numbers.last(); // 300
Avoid modifying the prototypes
of standard JavaScript objects.
84
All built-in objects
have a prototype property
that is read-only.
85
Unconfigurable Object Prototypes
86
1. Array.prototype = {
2. first: function () {
3. return this[0];
4. }
5. };
6.
7. var numbers = [100, 200, 300];
8.
9. numbers.first; // undefined
10. Object.getOwnPropertyDescriptor(Array, 'prototype');
11. // {configurable: false, … }
Arrow functions do not have
a prototype property.
87
Arrow Functions Do Not Have A prototype Pproperty
88
1. var Cloth = (type) => {
2. this.type = type;
3. };
4.
5. Cloth.prototype; // undefined
Inheritance
89
All objects inherit their
properties and methods from
their prototype.
90
Native Prototypes
91
1. (10).toFixed === Number.prototype.toFixed; // true
2. (true).valueOf === Boolean.prototype.valueOf; // true
3. ('A').trim === String.prototype.trim; // true
4. ({}).toString === Object.prototype.toString; // true
5. ([]).concat === Array.prototype.concat; // true
Overriding The Native Prototypes
92
1. var empty = {};
2. var script = { toString: () => 'Script' };
3. var ten = { valueOf: () => 10 };
4.
5. String(empty); // '[object Object]'
6. String(script); // ?
7. 'Java' + script; // ?
8. Number(empty); // NaN
9. Number(ten); // ?
10. ten + 20; // ?
1. var empty = {};
2. var script = { toString: () => 'Script' };
3. var ten = { valueOf: () => 10 };
4.
5. String(empty); // '[object Object]'
6. String(script); // 'Script'
7. 'Java' + script; // ?
8. Number(empty); // NaN
9. Number(ten); // ?
10. ten + 20; // ?
1. var empty = {};
2. var script = { toString: () => 'Script' };
3. var ten = { valueOf: () => 10 };
4.
5. String(empty); // '[object Object]'
6. String(script); // 'Script'
7. 'Java' + script; // 'JavaScript'
8. Number(empty); // NaN
9. Number(ten); // ?
10. ten + 20; // ?
1. var empty = {};
2. var script = { toString: () => 'Script' };
3. var ten = { valueOf: () => 10 };
4.
5. String(empty); // '[object Object]'
6. String(script); // 'Script'
7. 'Java' + script; // 'JavaScript'
8. Number(empty); // NaN
9. Number(ten); // 10
10. ten + 20; // ?
1. var empty = {};
2. var script = { toString: () => 'Script' };
3. var ten = { valueOf: () => 10 };
4.
5. String(empty); // '[object Object]'
6. String(script); // 'Script'
7. 'Java' + script; // 'JavaScript'
8. Number(empty); // NaN
9. Number(ten); // 10
10. ten + 20; // 30
A Custom Object
93
1. function Pig (name) { this.name = name; }
2. Pig.prototype.type = 'Pig';
3. Pig.prototype.sleep = function () { console.log('zZzZ…'); };
4.
5. var piggy = new Pig('Wilbur');
6.
7. piggy.name; // 'Wilbur'
8. piggy.type; // 'Pig'
9. piggy.sleep(); // 'zZzZ…';
10. piggy instanceof Pig; // true
11. piggy instanceof Object; // true
Shared Properties
94
1. function Player () { this.counting(); }
2. Player.prototype.counter = { value: 0 };
3. Player.prototype.counting = function () {
4. ++this.counter.value;
5. };
6.
7. var player1 = new Player();
8. player1.counter.value; // 1
9.
10. var player2 = new Player();
11. player2.counter.value; // 2
12. player1.counter.value; // 2
It is recommended to
define methods to all instances
through object prototype.
95
Instance Properties And Prototype Properties
96
1. function Robot () {
2. this.walk = function () {}
3. }
4. Robot.prototype.talk = function () {};
5.
6. var wat = new Robot(), eve = new Robot();
7.
8. wat.walk === eve.walk; // false
9. wat.talk === eve.talk; // true
10. wat.talk === Robot.prototype.talk; // true
11. wat.hasOwnProperty('walk'); // true
12. wat.hasOwnProperty('talk'); // false
Classical Inheritance With Object.create()
97
1. function Bird () {}
2. Bird.prototype.fly = function () {};
3.
4. function Pigeon () { Bird.call(this); }
5. Pigeon.prototype = Object.create(Bird.prototype);
6. Pigeon.prototype.constructor = Pigeon;
7. var pigeon = new Pigeon();
8.
9. Pigeon.prototype.__proto__ === Bird.prototype; // true
10. pigeon.fly === Pigeon.prototype.fly; // true
11. pigeon.fly === Bird.prototype.fly; // true
Override Methods
98
1. function Bird () {}
2. Bird.prototype.fly = function () { return 'Default'; };
3.
4. function Eagle () { Bird.call(this); }
5. Eagle.prototype = Object.create(Bird.prototype);
6. Eagle.prototype.constructor = Eagle;
7. Eagle.prototype.fly = function () { return 'Overrode'; };
8. var eagle = new Eagle();
9.
10. Eagle.prototype.__proto__ === Bird.prototype; // true
11. eagle.fly === Eagle.prototype.fly; // true
12. eagle.fly === Bird.prototype.fly; // false
Class
99
Class Declarations
100
1. class Bird {
2. constructor (type) {
3. this.type = type;
4. }
5. fly () {
6. console.log('Fly!');
7. }
8. }
9.
10. typeof Bird; // 'function'
Sub Classing With extends
101
1. class Penguin extends Bird {
2. constructor () {
3. super('Penguin');
4. }
5. fly () {
6. super.fly();
7. console.log('Penguin Fly!');
8. }
9. }
10.
11. Penguin.prototype.fly === Bird.prototype.fly; // false
Static Methods
102
1. class Food {
2. static calorie () {}
3. }
4.
5. function Drink () {}
6. Drink.calorie = function () {}
The best thing about JavaScript is
its implementation of functions. It
got almost everything right. But, as
you should expect with JavaScript,
it didn't get everything right.
- Douglas Crockford
103
Questions?
104
Reference
105
● JavaScript | CodeData
● Prototype-based programming - Wikipedia
● First-class function - Wikipedia
● JavaScript Guide - JavaScript | MDN
● JavaScript Tutorial | W3Schools
Practical JavaScript Programming
Reference Books
● JavaScript: The Good Parts
● Effective JavaScript
106
Practical JavaScript Programming
THANKS

More Related Content

What's hot (20)

PDF
HTTP Interceptors com AngularJS
Rodrigo Branas
 
PDF
Proyecto Final Android-SQLite
José Antonio Sandoval Acosta
 
PDF
Aller plus loin avec Doctrine2
André Tapia
 
PDF
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
matparisot
 
TXT
Index2
grateful7
 
PDF
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Ontico
 
DOCX
Danna y felix 10°
danna gabriela
 
PDF
ECMA2015 INSIDE
Jun Ho Lee
 
PDF
Silex al límite
Javier Eguiluz
 
PDF
Юнит тестирование в Zend Framework 2.0
zfconfua
 
PDF
Rambler.iOS #8: Чистые unit-тесты
RAMBLER&Co
 
PPTX
Java лаб13
Enkhee99
 
PDF
Most Common JavaScript Mistakes
Yoann Gotthilf
 
PDF
1- Sourcecode Array
Fajar Baskoro
 
PPT
JavaScript
Aleksandr Motsjonov
 
PDF
Testování prakticky
Filip Procházka
 
PDF
Java Thread Cronometro
jubacalo
 
PPT
Юнит тестирование в Zend Framework 2.0
zfconfua
 
PDF
Java script.trend(spec)
dynamis
 
PDF
Java AWT Calculadora
jubacalo
 
HTTP Interceptors com AngularJS
Rodrigo Branas
 
Proyecto Final Android-SQLite
José Antonio Sandoval Acosta
 
Aller plus loin avec Doctrine2
André Tapia
 
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
matparisot
 
Index2
grateful7
 
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Ontico
 
Danna y felix 10°
danna gabriela
 
ECMA2015 INSIDE
Jun Ho Lee
 
Silex al límite
Javier Eguiluz
 
Юнит тестирование в Zend Framework 2.0
zfconfua
 
Rambler.iOS #8: Чистые unit-тесты
RAMBLER&Co
 
Java лаб13
Enkhee99
 
Most Common JavaScript Mistakes
Yoann Gotthilf
 
1- Sourcecode Array
Fajar Baskoro
 
Testování prakticky
Filip Procházka
 
Java Thread Cronometro
jubacalo
 
Юнит тестирование в Zend Framework 2.0
zfconfua
 
Java script.trend(spec)
dynamis
 
Java AWT Calculadora
jubacalo
 

More from Wilson Su (12)

PDF
Mirage For Beginners
Wilson Su
 
PDF
NestJS
Wilson Su
 
PDF
The Jira How-To Guide
Wilson Su
 
PDF
The Future of Web Development
Wilson Su
 
PDF
Web Usability
Wilson Su
 
PDF
Puppeteer - Headless Chrome Node API
Wilson Su
 
PDF
Practical JavaScript Programming - Session 8/8
Wilson Su
 
PDF
Practical JavaScript Programming - Session 7/8
Wilson Su
 
PDF
Practical JavaScript Programming - Session 6/8
Wilson Su
 
PDF
Practical JavaScript Programming - Session 5/8
Wilson Su
 
PDF
Practical JavaScript Programming - Session 4/8
Wilson Su
 
PDF
Practical JavaScript Programming - Session 1/8
Wilson Su
 
Mirage For Beginners
Wilson Su
 
NestJS
Wilson Su
 
The Jira How-To Guide
Wilson Su
 
The Future of Web Development
Wilson Su
 
Web Usability
Wilson Su
 
Puppeteer - Headless Chrome Node API
Wilson Su
 
Practical JavaScript Programming - Session 8/8
Wilson Su
 
Practical JavaScript Programming - Session 7/8
Wilson Su
 
Practical JavaScript Programming - Session 6/8
Wilson Su
 
Practical JavaScript Programming - Session 5/8
Wilson Su
 
Practical JavaScript Programming - Session 4/8
Wilson Su
 
Practical JavaScript Programming - Session 1/8
Wilson Su
 
Ad

Practical JavaScript Programming - Session 3/8

  • 3. Outline 3 Practical JavaScript Programming Chapter 5. ● Function Definitions ● Function Parameters ● The Arguments Object ● What is ‘this’? ● Function Invocation ● Closures Functions Chapter 6. Constructors And Prototypes ● Constructors ● Prototypes ● Inheritance ● Class
  • 4. 4 Wilson Su Front-end Developer, HIE ● 6 years in web design ● Specialize in JavaScript / CSS / HTML / OOP / Git ● Familiar with PHP / Design Pattern ● Interested in UI & Ix Design [email protected]
  • 6. Parentheses 6 1. 5.toString(); // SyntaxError 2. (5).toString(); // '5' 3. 4. var good = { grade: 'A' }, bad = { grade: 'F' }; 5. var score = 75; 6. 7. if (score > 60) { 8. good.grade; // 'A' 9. } else { 10. bad.grade; 11. } 12. 13. (score > 60 ? good : bad).grade; // 'A'
  • 8. In JavaScript, functions are first-class objects. 8
  • 10. 3 Ways To Define A Function 10 1. /* Function declarations */ 2. function name ([param[, param[..., param]]]) { 3. [statements] 4. } 5. 6. /* Function expressions */ 7. var name = function [name] ([param[, param[..., param]]]) { 8. [statements] 9. } 10. 11. /* Function Constructor */ 12. var name = new Function([param[, param[..., param]],] body);
  • 11. Function Declarations 11 1. function echo (value) { return value; } 2. typeof echo; // 'function' 3. echo.name; // 'echo' 4. echo.length; // 1 5. echo('ABC'); // 'ABC' 6. 7. function () {} // SyntaxError
  • 12. Function Expressions 12 1. var multiply = function (x, y) { 2. return x * y; 3. }; 4. 5. typeof multiply; // 'function' 6. multiply.name; // 'multiply' 7. multiply.length; // 2 8. multiply(2, 3); // 6 9. 10. (function (value) { return value; }) 11. // function (value) { return value; }
  • 13. Named Function Expressions 13 1. var calcalate = function calc (v1, v2) { 2. console.log(typeof calc); // 'function' 3. console.log(calcalate === calc); // true 4. return v1 + v2; 5. } 6. 7. typeof calcalate; // 'function' 8. calcalate.name; // 'calc' 9. calcalate.length; // 2 10. calcalate(2, 3); // 5 11. calc; // ? 1. var calcalate = function calc (v1, v2) { 2. console.log(typeof calc); // 'function' 3. console.log(calcalate === calc); // true 4. return v1 + v2; 5. } 6. 7. typeof calcalate; // 'function' 8. calcalate.name; // 'calc' 9. calcalate.length; // 2 10. calcalate(2, 3); // 5 11. calc; // ReferenceError
  • 14. The Function() Constructor 14 1. var subtract = new Function('x', 'y', 'return x - y'); 2. 3. typeof subtract; // 'function' 4. subtract.name; // 'anonymous' 5. subtract.length; // 2 6. subtract(18, 3); // 15
  • 15. Functions created with the Function constructor always are created in the global scope. 15
  • 16. The Function() Constructor Create Functions In The Global Scope 16 1. var uppercaser = function (skill) { 2. return new Function('return skill.toUpperCase()'); 3. }; 4. var uppercase = uppercaser('html'); 5. var skill = 'css'; 6. 7. uppercase('js'); // ? 1. var uppercaser = function (skill) { 2. return new Function('return skill.toUpperCase()'); 3. }; 4. var uppercase = uppercaser('html'); 5. var skill = 'css'; 6. 7. uppercase('js'); // 'CSS'
  • 17. Defining Object Methods 17 1. var dog = { 2. bark: function bowwow () { 3. console.log('Bowwow!'); 4. } 5. }; 6. 7. typeof dog.bark; // 'function' 8. dog.bark.name; // 'bowwow' 9. dog.bark.length; // 0 10. dog.bark(); // 'Bowwow!'
  • 18. Defining Object Methods In A Shorter Syntax 18 1. var cat = { 2. meow () { 3. console.log('Meow~'); 4. } 5. }; 6. 7. typeof cat.meow; // 'function' 8. cat.meow.name; // 'meow' 9. cat.meow.length; // 0 10. cat.meow(); // 'Meow~'
  • 19. Function Return 19 1. function noop () {} 2. function nothing () { return; } 3. function echo (value) { return value; } 4. 5. noop(true); // undefined 6. nothing('Hi'); // undefined 7. echo([10, 20]); // (2) [10, 20]
  • 20. Function Hoisting 20 1. hello(); // 'Hello!' 2. aloha(); // ? 3. 4. function hello () { 5. return 'Hello!'; 6. } 7. 8. var aloha = function () { 9. return 'Aloha!'; 10. }; 1. hello(); // 'Hello!' 2. aloha(); // TypeError 3. 4. function hello () { 5. return 'Hello!'; 6. } 7. 8. var aloha = function () { 9. return 'Aloha!'; 10. };
  • 21. Nested Functions 21 1. function outer () { 2. function inner () { 3. return 'Inner'; 4. } 5. return inner(); 6. } 7. 8. outer(); // 'Inner'; 9. inner(); // ? 1. function outer () { 2. function inner () { 3. return 'Inner'; 4. } 5. return inner(); 6. } 7. 8. outer(); // 'Inner'; 9. inner(); // ReferenceError
  • 22. Arrow Functions 22 1. var remove = (target, array) => { 2. var index = array.indexOf(target); 3. return index > -1 ? !!array.splice(index, 1) : false; 4. }; 5. var concat = (list1, list2) => list1.concat(list2); 6. var numbers = [100, 200, 300]; 7. 8. remove(200, numbers); // true 9. numbers; // (2) [100, 300] 10. concat(numbers, [500, 700]); // (4) [100, 300, 500, 700] 11. numbers; // ? 1. var remove = (target, array) => { 2. var index = array.indexOf(target); 3. return index > -1 ? !!array.splice(index, 1) : false; 4. }; 5. var concat = (list1, list2) => list1.concat(list2); 6. var numbers = [100, 200, 300]; 7. 8. remove(200, numbers); // true 9. numbers; // (2) [100, 300] 10. concat(numbers, [500, 700]); // (4) [100, 300, 500, 700] 11. numbers; // (2) [100, 300]
  • 23. More Examples With Arrow Functions 23 1. var noop = () => {}; 2. var book = title => ({ title }); 3. 4. book('Zero to One'); // {title: 'Zero to One'} 5. 6. [{ id: 10 }, { id: 20 }, { id: 30 }].map(item => item.id); 7. // (3) [10, 20, 30]
  • 24. Generator Functions 24 1. function* generator (x) { 2. yield x * 10; 3. yield x + 50; 4. } 5. 6. var iterator = generator(10); 7. 8. typeof generator; // 'function' 9. typeof iterator; // 'object' 10. 11. iterator.next(); // {value: 100, done: false} 12. iterator.next(); // {value: 60, done: false} 13. iterator.next(); // {value: undefined, done: true}
  • 26. Parameter Defaults 26 1. function add (x, y) { 2. console.log(x); // 5 3. console.log(y); // undefined 4. console.log(x + y); // NaN 5. x = x || 0; 6. y = y || 0; 7. return x + y; 8. } 9. 10. add(5); // 5
  • 27. Passed By Value / Passed By Reference 27 1. function update (string, object, array) { 2. string = 'aloha'; 3. object.id = 2; 4. array = []; 5. } 6. 7. var string = 'hello', object = { id: 1 }, array = [10, 20]; 8. 9. update(string, object, array); 10. console.log(string); // ? 11. console.log(object); // ? 12. console.log(array); // ? 1. function update (string, object, array) { 2. string = 'aloha'; 3. object.id = 2; 4. array = []; 5. } 6. 7. var string = 'hello', object = { id: 1 }, array = [10, 20]; 8. 9. update(string, object, array); 10. console.log(string); // 'hello' 11. console.log(object); // ? 12. console.log(array); // ? 1. function update (string, object, array) { 2. string = 'aloha'; 3. object.id = 2; 4. array = []; 5. } 6. 7. var string = 'hello', object = { id: 1 }, array = [10, 20]; 8. 9. update(string, object, array); 10. console.log(string); // 'hello' 11. console.log(object); // {id: 2} 12. console.log(array); // ? 1. function update (string, object, array) { 2. string = 'aloha'; 3. object.id = 2; 4. array = []; 5. } 6. 7. var string = 'hello', object = { id: 1 }, array = [10, 20]; 8. 9. update(string, object, array); 10. console.log(string); // 'hello' 11. console.log(object); // {id: 2} 12. console.log(array); // (2) [10, 20]
  • 28. Default And Destructured Parameters 28 1. function fn1 (x = 0) {} 2. 3. function fn2 (x = y(), z = []) {} 4. 5. function fn3 (x, y = x, z = y + 1) {} 6. 7. function fn4 ({ multiplier = 3 }, [x, y, z = 5]) {}
  • 29. Rest Parameters 29 1. function join (...args) { 2. return args.join(' '); 3. } 4. function sum (...[x, y, z]) { 5. return x + y + z; 6. } 7. 8. join('Ryan', 'likes', 'JS'); // 'Ryan likes JS' 9. 10. sum(1); // NaN 11. sum(1, 2, 3); // 6 12. sum(1, 2, 3, 4); // 6
  • 31. The arguments Object 31 1. function fn () { 2. console.log(arguments); 3. } 4. 5. fn(10, 20); // (2) [10, 20]
  • 32. The arguments object is not a real array. 32
  • 33. The arguments Object 33 1. function fn () { 2. console.log(arguments.length); // 2 3. console.log(arguments[0]); // 10 4. console.log(arguments[1]); // 20 5. console.log(typeof arguments); // 'object' 6. console.log(arguments instanceof Array); // false 7. } 8. 9. fn(10, 20);
  • 34. From arguments To An Array 34 1. function toArray1 () { 2. return Array.prototype.slice.call(arguments, 0); 3. } 4. function toArray2 () { 5. return [].slice.call(arguments, 0); 6. } 7. 8. toArray1(1, 2, 3); // (3) [1, 2, 3] 9. toArray1(1, 2, 3) instanceof Array; // true 10. 11. toArray2(4, 5, 6); // (3) [4, 5, 6] 12. toArray2(4, 5, 6) instanceof Array; // true
  • 35. From arguments To An Array 35 1. function toArray3 () { 2. return arguments.length === 1 3. ? [arguments[0]] 4. : Array.apply(null, arguments); 5. } 6. 7. /* ES6 */ 8. function toArray4 () { 9. return Array.from(arguments); 10. }
  • 36. Destructuring 36 1. function fn () { 2. var args = [...arguments]; 3. var [x, y, ...rest] = arguments; 4. 5. console.log(args); // (5) [10, 20, 30, 40, 50] 6. console.log(args instanceof Array); // true 7. console.log(x); // 10 8. console.log(y); // 20 9. console.log(rest); // (3) [30, 40, 50] 10. } 11. 12. fn(10, 20, 30, 40, 50);
  • 37. Arrow funtions do not bind an arguments object. 37
  • 38. Arrow Funtions 38 1. var fn = () => arguments; 2. var calc = function () { 3. var fn = (multiple) => arguments[0] * multiple; 4. return fn(3); 5. }; 6. 7. fn(); // ? 8. calc(8); // ? 1. var fn = () => arguments; 2. var calc = function () { 3. var fn = (multiple) => arguments[0] * multiple; 4. return fn(3); 5. }; 6. 7. fn(); // ReferenceError 8. calc(8); // ? 1. var fn = () => arguments; 2. var calc = function () { 3. var fn = (multiple) => arguments[0] * multiple; 4. return fn(3); 5. }; 6. 7. fn(); // ReferenceError 8. calc(8); // 24
  • 40. Global Context 40 1. /* In a browser */ 2. this; // Window { … } 3. this === window; // true 4. 5. /* In Node */ 6. this; // {} 7. this === module.exports; // true
  • 41. Function Context 41 1. /* In a browser */ 2. var that = function () { return this; }; 3. that(); // Window { … } 4. that() === window; // true 5. 6. /* In Node */ 7. var that = function () { return this; }; 8. that(); // { global: …, console: … } 9. that() === global; // true
  • 42. Nested Functions 42 1. var root = this; 2. function outer () { 3. function inner () { return this; } 4. var that = inner(); 5. 6. console.log(that); // Window { … } 7. console.log(that === window); // true 8. console.log(that === this); // true 9. console.log(that === root); // true 10. } 11. 12. outer();
  • 43. The Function Constructor 43 1. var self = new Function('return this'); 2. 3. self(); // Window { … } 4. self() === window; // true 5. self() === this; // true
  • 44. Object Methods 44 1. var data = { 2. self: function () { 3. return this; 4. } 5. }; 6. 7. data.self(); // {self: function} 8. data.self() === data; // true
  • 45. Object Methods Refer To Global Functions 45 1. function age () { return this._age; } 2. 3. var dog = { _age: 5, age: age }; 4. var cat = { _age: 1, age: age }; 5. 6. dog.age(); // 5 7. cat.age(); // 1
  • 46. Getters And Setters 46 1. var data = { 2. x: 10, 3. get y () { return this.x + 5; }, 4. set z (z) { this.x = this.x * z; } 5. }; 6. 7. data.z = 3; 8. 9. console.log(data.x); // ? 10. console.log(data.y); // ? 1. var data = { 2. x: 10, 3. get y () { return this.x + 5; }, 4. set z (z) { this.x = this.x * z; } 5. }; 6. 7. data.z = 3; 8. 9. console.log(data.x); // 30 10. console.log(data.y); // ? 1. var data = { 2. x: 10, 3. get y () { return this.x + 5; }, 4. set z (z) { this.x = this.x * z; } 5. }; 6. 7. data.z = 3; 8. 9. console.log(data.x); // 30 10. console.log(data.y); // 35
  • 47. Method Chaining 47 1. [2, 5, 1, 7, 4] 2. .sort(function (a, b) { return a - b }) 3. .reverse() 4. .map(function (n) { return n * 10; }); 5. 6. // (6) [70, 50, 40, 20, 10]
  • 48. Chainable Methods 48 1. var list = { 2. items: [3, 8, 5], 3. push: function (value) { 4. this.items.push(value); return this; 5. }, 6. remove: function (value) { 7. var index = this.items.indexOf(value); 8. if (index > -1) { this.items.splice(index, 1); } 9. return this; 10. } 11. }; 12. list.push(7).push(2).remove(8).items; 13. // (4) [3, 5, 7, 2]
  • 49. An arrow function does not create its own this value. 49
  • 50. Arrow Functions Used As Methods 50 1. var root = this; 2. var object = { 3. origin: function () { return this; }, 4. short: () => this 5. }; 6. 7. object.origin() === object; // true 8. object.origin() === object.short(); // false 9. object.short() === root; // true
  • 51. Common Mistake With this 51 1. var zack = { 2. nickname: 'Z', 3. greet: function () { 4. console.log('Hi, I’m ' + this.nickname); 5. } 6. }; 7. var greet = zack.greet; 8. 9. greet(); // ? 1. var zack = { 2. nickname: 'Z', 3. greet: function () { 4. console.log('Hi, I’m ' + this.nickname); 5. } 6. }; 7. var greet = zack.greet; 8. 9. greet(); // 'Hi, I’m undefined'
  • 53. Invoking Functions 53 1. function add (x, y) { 2. return x + y; 3. } 4. 5. add(5, 8); // 13 6. Math.floor(3.14); // 3
  • 54. Invoking Object Methods 54 1. var employee = { 2. title: 'PM', 3. name: 'Alex', 4. info: function () { 5. return this.name + ' is a ' + this.title; 6. } 7. }; 8. 9. employee.info(); // 'Alex is a PM'
  • 55. Function Call 55 1. var name = 'Window'; 2. var jack = { name: 'Jack' }, nick = { name: 'Nick' }; 3. 4. function whoami () { return this.name; } 5. 6. whoami(); // 'Window' 7. whoami.call(this); // 'Window' 8. whoami.call(jack); // 'Jack' 9. whoami.call(nick); // 'Nick' 10. 11. [1, 2].concat.call([3, 4], [5, 6]); // ? 1. var name = 'Window'; 2. var jack = { name: 'Jack' }, nick = { name: 'Nick' }; 3. 4. function whoami () { return this.name; } 5. 6. whoami(); // 'Window' 7. whoami.call(this); // 'Window' 8. whoami.call(jack); // 'Jack' 9. whoami.call(nick); // 'Nick' 10. 11. [1, 2].concat.call([3, 4], [5, 6]); // (4) [3, 4, 5, 6]
  • 56. Function Apply 56 1. Math.max(5, 2, 7, 4); // 7 2. Math.max.apply(null, [9, 1, 3, 6]); // 9 3. 4. function sum () { 5. return [].slice.call(arguments, 0).reduce((a, b) => a + b); 6. } 7. 8. sum.apply(null, [1, 2, 3, 4, 5]); // 15
  • 57. The function.bind() Method 57 1. function color () { return this.color; } 2. 3. var yellow = { color: '#ff3' }; 4. var purple = { color: '#609' }; 5. 6. typeof color.bind(yellow); // 'function' 7. color.bind(yellow)(); // '#ff3' 8. 9. typeof color.bind(purple); // 'function' 10. color.bind(purple)(); // '#609'
  • 58. Currying 58 1. function add (x, y) { 2. return x + y; 3. } 4. 5. var add5 = add.bind(null, 5); // Curried 6. 7. add(5, 3); // 8 8. 9. add5(10); // ? 10. add5(60); // ? 1. function add (x, y) { 2. return x + y; 3. } 4. 5. var add5 = add.bind(null, 5); // Curried 6. 7. add(5, 3); // 8 8. 9. add5(10); // 15 10. add5(60); // ? 1. function add (x, y) { 2. return x + y; 3. } 4. 5. var add5 = add.bind(null, 5); // Curried 6. 7. add(5, 3); // 8 8. 9. add5(10); // 15 10. add5(60); // 65
  • 59. Self-Invoking Functions (Immediately Invoked Function Expression) 59 1. var number = (function (x) { return x + 3; })(7); 2. console.log(number); // 10 3. 4. (() => 'blabla')(); // 'blabla' 5. 6. (function (_) { 7. var title = 'My Home'; 8. console.log(window.title); // undefined 9. })(underscore);
  • 61. A closure is the combination of a function and the lexical environment within which that function was declared. 61
  • 62. Lexical Scope / Static Scope 62 1. function outer () { 2. var skill = 'JavaScript'; 3. function inner () { 4. console.log(skill); // 'JavaScript' 5. } 6. inner(); 7. console.log(title); // 'Tutorial' 8. } 9. var title = 'Tutorial'; 10. 11. outer();
  • 63. inner() outer() global console.log(skill); console.log(title); (NONE) skill = 'JavaScript' title = 'Tutorial' Scope Chain 63 Closures ScopeChain Reference to outer lexical enviroment
  • 64. Closures 64 1. function doubler (n) { return function () { return n * 2; }; } 2. function subtractor (x) { return (y) => (x = x - y); }; 3. 4. var sixteen = doubler(8); 5. var subtract = subtractor(100); 6. 7. sixteen(); // 16 8. 9. subtract(15); // ? 10. subtract(20); // ? 1. function doubler (n) { return function () { return n * 2; }; } 2. function subtractor (x) { return (y) => (x = x - y); }; 3. 4. var sixteen = doubler(8); 5. var subtract = subtractor(100); 6. 7. sixteen(); // 16 8. 9. subtract(15); // 85 10. subtract(20); // ? 1. function doubler (n) { return function () { return n * 2; }; } 2. function subtractor (x) { return (y) => (x = x - y); }; 3. 4. var sixteen = doubler(8); 5. var subtract = subtractor(100); 6. 7. sixteen(); // 16 8. 9. subtract(15); // 85 10. subtract(20); // 65
  • 65. 1. function doubler (n) { 2. return function () { 3. return n * 2; 4. }; 5. } 6. var sixteen = doubler(8); 65 Closure The instance sixteen maintains a reference to its lexical environment, within which the variable n exists.
  • 66. Using Closure To Define Private Properties 66 1. function Circle (radius) { 2. this.getRadius = function () { return radius; }; 3. this.setRadius = function (value) { radius = value; }; 4. } 5. var circle = new Circle(10); 6. 7. circle.radius; // undefined 8. circle.getRadius(); // 10 9. circle.setRadius(20); // 20 10. circle.getRadius(); // 20
  • 67. A Common Mistake With Closure 67 1. var i = 0, fn = {}; 2. 3. for (; i < 5; ++i) { 4. fn['get' + i] = function () { 5. console.log(i); 6. }; 7. } 8. 9. fn.get2(); // ? 1. var i = 0, fn = {}; 2. 3. for (; i < 5; ++i) { 4. fn['get' + i] = function () { 5. console.log(i); 6. }; 7. } 8. 9. fn.get2(); // 5
  • 70. Constructors 70 1. function Fruit (name) { 2. this.name = name; 3. } 4. 5. var kiwi = new Fruit('Kiwi'); 6. 7. kiwi.name; // 'Kiwi'
  • 71. Arrow functions cannot be used as constructors. 71
  • 72. Arrow Functions Cannot Be Used As Constructors 72 1. var Cloth = (type) => { 2. this.type = type; 3. }; 4. 5. new Cloth('Shirt'); // TypeError
  • 74. Prototype-based Programming Prototype-based programming is a style of object-oriented programming in which behaviour reuse is performed via a process of reusing existing objects via delegation that serve as prototypes. – Wiki 74 Prototypes
  • 75. The Special Object Properties 75 ● object.prototype returns a reference to the prototype for a class of objects. ● object.__proto__ returns a reference to the internal prototype of the specified object. Prototypes
  • 76. The Prototype Chain Of An Instance 76 1. function Fruit (name) { 2. this.name = name; 3. } 4. 5. var kiwi = new Fruit(); 6. 7. kiwi.__proto__ === Fruit.prototype; // true 8. kiwi.__proto__.__proto__ === Object.prototype; // true 9. kiwi.__proto__.__proto__.__proto__; // * null 10. 11. kiwi.__proto__ === Object.getPrototypeOf(kiwi); // true
  • 77. 77 var kiwi = new Object(); kiwi.__proto__ = Fruit.prototype; Fruit.call(kiwi); 1 2 3 What Does The new Operator Do? Prototypes var kiwi = new Fruit(); ⇒ return kiwi;4
  • 78. The Prototype Chain Of A Constructor 78 1. function Dog () {} 2. Dog.prototype.self = function () { return this; }; 3. 4. var dog = new Dog(); 5. 6. Dog.__proto__ === Function.prototype; // true 7. Dog.__proto__.__proto__ === Object.prototype; // true 8. Dog.__proto__.__proto__.__proto__; // * null 9. 10. Dog.prototype.constructor === Dog; // true 11. dog.constructor === Dog; // true
  • 79. FunctionsInstances Prototypes d1 function Function () {} function Object () {} function Dog () {} Function.prototype Object.prototype Dog.prototype var … = new Dog(); d2 o1 var … = new Object(); o2 __proto__ prototype constructor null
  • 80. Creating Objects Using Object.create() 80 1. var animal = { gender: 'Unknown' }; 2. var human = Object.create(animal); 3. var female = Object.create(human, { 4. gender: { value: 'Female' } 5. }); 6. 7. human.gender; // 'Unknown' 8. human.__proto__ === animal; // true 9. 10. female.gender; // 'Female' 11. female.__proto__ === human; // true 12. female.__proto__.__proto__ === animal; // true
  • 81. Creating Objects Using Object.create(null) 81 1. var common = {}; 2. var uncommon = Object.create(null); 3. 4. common.constructor === Object; // true 5. common.__proto__ === Object.prototype; // true 6. 7. uncommon.constructor; // undefined 8. uncommon.__proto__; // undefined
  • 82. You can add properties and methods to the prototype of built-in objects. 82
  • 83. Adding Methods To Array.prototype 83 1. Array.prototype.first = function () { 2. return this[0]; 3. }; 4. 5. Array.prototype.last = function () { 6. return this[this.length - 1]; 7. }; 8. 9. var numbers = [100, 200, 300]; 10. 11. numbers.first(); // 100 12. numbers.last(); // 300
  • 84. Avoid modifying the prototypes of standard JavaScript objects. 84
  • 85. All built-in objects have a prototype property that is read-only. 85
  • 86. Unconfigurable Object Prototypes 86 1. Array.prototype = { 2. first: function () { 3. return this[0]; 4. } 5. }; 6. 7. var numbers = [100, 200, 300]; 8. 9. numbers.first; // undefined 10. Object.getOwnPropertyDescriptor(Array, 'prototype'); 11. // {configurable: false, … }
  • 87. Arrow functions do not have a prototype property. 87
  • 88. Arrow Functions Do Not Have A prototype Pproperty 88 1. var Cloth = (type) => { 2. this.type = type; 3. }; 4. 5. Cloth.prototype; // undefined
  • 90. All objects inherit their properties and methods from their prototype. 90
  • 91. Native Prototypes 91 1. (10).toFixed === Number.prototype.toFixed; // true 2. (true).valueOf === Boolean.prototype.valueOf; // true 3. ('A').trim === String.prototype.trim; // true 4. ({}).toString === Object.prototype.toString; // true 5. ([]).concat === Array.prototype.concat; // true
  • 92. Overriding The Native Prototypes 92 1. var empty = {}; 2. var script = { toString: () => 'Script' }; 3. var ten = { valueOf: () => 10 }; 4. 5. String(empty); // '[object Object]' 6. String(script); // ? 7. 'Java' + script; // ? 8. Number(empty); // NaN 9. Number(ten); // ? 10. ten + 20; // ? 1. var empty = {}; 2. var script = { toString: () => 'Script' }; 3. var ten = { valueOf: () => 10 }; 4. 5. String(empty); // '[object Object]' 6. String(script); // 'Script' 7. 'Java' + script; // ? 8. Number(empty); // NaN 9. Number(ten); // ? 10. ten + 20; // ? 1. var empty = {}; 2. var script = { toString: () => 'Script' }; 3. var ten = { valueOf: () => 10 }; 4. 5. String(empty); // '[object Object]' 6. String(script); // 'Script' 7. 'Java' + script; // 'JavaScript' 8. Number(empty); // NaN 9. Number(ten); // ? 10. ten + 20; // ? 1. var empty = {}; 2. var script = { toString: () => 'Script' }; 3. var ten = { valueOf: () => 10 }; 4. 5. String(empty); // '[object Object]' 6. String(script); // 'Script' 7. 'Java' + script; // 'JavaScript' 8. Number(empty); // NaN 9. Number(ten); // 10 10. ten + 20; // ? 1. var empty = {}; 2. var script = { toString: () => 'Script' }; 3. var ten = { valueOf: () => 10 }; 4. 5. String(empty); // '[object Object]' 6. String(script); // 'Script' 7. 'Java' + script; // 'JavaScript' 8. Number(empty); // NaN 9. Number(ten); // 10 10. ten + 20; // 30
  • 93. A Custom Object 93 1. function Pig (name) { this.name = name; } 2. Pig.prototype.type = 'Pig'; 3. Pig.prototype.sleep = function () { console.log('zZzZ…'); }; 4. 5. var piggy = new Pig('Wilbur'); 6. 7. piggy.name; // 'Wilbur' 8. piggy.type; // 'Pig' 9. piggy.sleep(); // 'zZzZ…'; 10. piggy instanceof Pig; // true 11. piggy instanceof Object; // true
  • 94. Shared Properties 94 1. function Player () { this.counting(); } 2. Player.prototype.counter = { value: 0 }; 3. Player.prototype.counting = function () { 4. ++this.counter.value; 5. }; 6. 7. var player1 = new Player(); 8. player1.counter.value; // 1 9. 10. var player2 = new Player(); 11. player2.counter.value; // 2 12. player1.counter.value; // 2
  • 95. It is recommended to define methods to all instances through object prototype. 95
  • 96. Instance Properties And Prototype Properties 96 1. function Robot () { 2. this.walk = function () {} 3. } 4. Robot.prototype.talk = function () {}; 5. 6. var wat = new Robot(), eve = new Robot(); 7. 8. wat.walk === eve.walk; // false 9. wat.talk === eve.talk; // true 10. wat.talk === Robot.prototype.talk; // true 11. wat.hasOwnProperty('walk'); // true 12. wat.hasOwnProperty('talk'); // false
  • 97. Classical Inheritance With Object.create() 97 1. function Bird () {} 2. Bird.prototype.fly = function () {}; 3. 4. function Pigeon () { Bird.call(this); } 5. Pigeon.prototype = Object.create(Bird.prototype); 6. Pigeon.prototype.constructor = Pigeon; 7. var pigeon = new Pigeon(); 8. 9. Pigeon.prototype.__proto__ === Bird.prototype; // true 10. pigeon.fly === Pigeon.prototype.fly; // true 11. pigeon.fly === Bird.prototype.fly; // true
  • 98. Override Methods 98 1. function Bird () {} 2. Bird.prototype.fly = function () { return 'Default'; }; 3. 4. function Eagle () { Bird.call(this); } 5. Eagle.prototype = Object.create(Bird.prototype); 6. Eagle.prototype.constructor = Eagle; 7. Eagle.prototype.fly = function () { return 'Overrode'; }; 8. var eagle = new Eagle(); 9. 10. Eagle.prototype.__proto__ === Bird.prototype; // true 11. eagle.fly === Eagle.prototype.fly; // true 12. eagle.fly === Bird.prototype.fly; // false
  • 100. Class Declarations 100 1. class Bird { 2. constructor (type) { 3. this.type = type; 4. } 5. fly () { 6. console.log('Fly!'); 7. } 8. } 9. 10. typeof Bird; // 'function'
  • 101. Sub Classing With extends 101 1. class Penguin extends Bird { 2. constructor () { 3. super('Penguin'); 4. } 5. fly () { 6. super.fly(); 7. console.log('Penguin Fly!'); 8. } 9. } 10. 11. Penguin.prototype.fly === Bird.prototype.fly; // false
  • 102. Static Methods 102 1. class Food { 2. static calorie () {} 3. } 4. 5. function Drink () {} 6. Drink.calorie = function () {}
  • 103. The best thing about JavaScript is its implementation of functions. It got almost everything right. But, as you should expect with JavaScript, it didn't get everything right. - Douglas Crockford 103
  • 105. Reference 105 ● JavaScript | CodeData ● Prototype-based programming - Wikipedia ● First-class function - Wikipedia ● JavaScript Guide - JavaScript | MDN ● JavaScript Tutorial | W3Schools Practical JavaScript Programming
  • 106. Reference Books ● JavaScript: The Good Parts ● Effective JavaScript 106 Practical JavaScript Programming
  • 107. THANKS