SlideShare uma empresa Scribd logo
1 de 107
Baixar para ler offline
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

Mais conteúdo relacionado

Mais procurados

HTTP Interceptors com AngularJS
HTTP Interceptors com AngularJSHTTP Interceptors com AngularJS
HTTP Interceptors com AngularJSRodrigo Branas
 
Aller plus loin avec Doctrine2
Aller plus loin avec Doctrine2Aller plus loin avec Doctrine2
Aller plus loin avec Doctrine2André Tapia
 
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascriptECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascriptmatparisot
 
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...Ontico
 
ECMA2015 INSIDE
ECMA2015 INSIDEECMA2015 INSIDE
ECMA2015 INSIDEJun Ho Lee
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0zfconfua
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRAMBLER&Co
 
Java лаб13
Java лаб13Java лаб13
Java лаб13Enkhee99
 
Most Common JavaScript Mistakes
Most Common JavaScript MistakesMost Common JavaScript Mistakes
Most Common JavaScript MistakesYoann Gotthilf
 
Java Thread Cronometro
Java Thread CronometroJava Thread Cronometro
Java Thread Cronometrojubacalo
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0zfconfua
 
Java script.trend(spec)
Java script.trend(spec)Java script.trend(spec)
Java script.trend(spec)dynamis
 
Java AWT Calculadora
Java AWT CalculadoraJava AWT Calculadora
Java AWT Calculadorajubacalo
 

Mais procurados (20)

HTTP Interceptors com AngularJS
HTTP Interceptors com AngularJSHTTP Interceptors com AngularJS
HTTP Interceptors com AngularJS
 
Proyecto Final Android-SQLite
Proyecto Final Android-SQLiteProyecto Final Android-SQLite
Proyecto Final Android-SQLite
 
Aller plus loin avec Doctrine2
Aller plus loin avec Doctrine2Aller plus loin avec Doctrine2
Aller plus loin avec Doctrine2
 
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascriptECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
ECMAscript 2015 aka ES6 : à la découverte du nouveau javascript
 
Index2
Index2Index2
Index2
 
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
Angular 2 не так уж и плох... А если задуматься, то и просто хорош / Алексей ...
 
Danna y felix 10°
Danna y felix 10°Danna y felix 10°
Danna y felix 10°
 
ECMA2015 INSIDE
ECMA2015 INSIDEECMA2015 INSIDE
ECMA2015 INSIDE
 
Silex al límite
Silex al límiteSilex al límite
Silex al límite
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тесты
 
Java лаб13
Java лаб13Java лаб13
Java лаб13
 
Most Common JavaScript Mistakes
Most Common JavaScript MistakesMost Common JavaScript Mistakes
Most Common JavaScript Mistakes
 
1- Sourcecode Array
1- Sourcecode Array1- Sourcecode Array
1- Sourcecode Array
 
JavaScript
JavaScriptJavaScript
JavaScript
 
Testování prakticky
Testování praktickyTestování prakticky
Testování prakticky
 
Java Thread Cronometro
Java Thread CronometroJava Thread Cronometro
Java Thread Cronometro
 
Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0Юнит тестирование в Zend Framework 2.0
Юнит тестирование в Zend Framework 2.0
 
Java script.trend(spec)
Java script.trend(spec)Java script.trend(spec)
Java script.trend(spec)
 
Java AWT Calculadora
Java AWT CalculadoraJava AWT Calculadora
Java AWT Calculadora
 

Mais de Wilson Su

Mirage For Beginners
Mirage For BeginnersMirage For Beginners
Mirage For BeginnersWilson Su
 
The Jira How-To Guide
The Jira How-To GuideThe Jira How-To Guide
The Jira How-To GuideWilson Su
 
The Future of Web Development
The Future of Web DevelopmentThe Future of Web Development
The Future of Web DevelopmentWilson Su
 
Web Usability
Web UsabilityWeb Usability
Web UsabilityWilson Su
 
Puppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node APIPuppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node APIWilson Su
 
Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8Wilson Su
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Wilson Su
 
Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Wilson Su
 
Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8Wilson Su
 
Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8Wilson Su
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Wilson Su
 

Mais de Wilson Su (12)

Mirage For Beginners
Mirage For BeginnersMirage For Beginners
Mirage For Beginners
 
NestJS
NestJSNestJS
NestJS
 
The Jira How-To Guide
The Jira How-To GuideThe Jira How-To Guide
The Jira How-To Guide
 
The Future of Web Development
The Future of Web DevelopmentThe Future of Web Development
The Future of Web Development
 
Web Usability
Web UsabilityWeb Usability
Web Usability
 
Puppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node APIPuppeteer - Headless Chrome Node API
Puppeteer - Headless Chrome Node API
 
Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8
 
Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8Practical JavaScript Programming - Session 7/8
Practical JavaScript Programming - Session 7/8
 
Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8
 
Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8
 
Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8Practical JavaScript Programming - Session 4/8
Practical JavaScript Programming - Session 4/8
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8
 

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 wilson_su@trend.com.tw
  • 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