Slide 1

Slide 1 text

reducing the wat-factor of JS JavaScript’s Difficult Concepts Explained PRESENTED BY JEFF CAROUTH @jcarouth

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Wat? 0.

Slide 4

Slide 4 text

var_dump([] + []);! !

Slide 5

Slide 5 text

var_dump([] + []);! // => []!

Slide 6

Slide 6 text

console.dir([] + []);

Slide 7

Slide 7 text

console.dir([] + []);! // => ''

Slide 8

Slide 8 text

WAT? https://www.destroyallsoftware.com/talks/wat

Slide 9

Slide 9 text

Scope 1.

Slide 10

Slide 10 text

global& function

Slide 11

Slide 11 text

foo = "I am a globally-scoped var.";! ! console.log(foo);! ! // > I am a globally-scoped var.!

Slide 12

Slide 12 text

foo = "I am a globally-scoped var.";! ! ! function sayFoo() {! console.log(foo);! }! ! sayFoo();! ! // > I am a globally-scoped var.!

Slide 13

Slide 13 text

foo = "I am a globally-scoped var.";! ! function sayFoo() {! console.log(foo);! }! ! function defineFoo() {! foo = "I am set in defineFoo()";! }

Slide 14

Slide 14 text

foo = "I am a globally-scoped var.";! ! function sayFoo() {! console.log(foo);! }! ! function defineFoo() {! foo = "I am set in defineFoo()";! }! ! defineFoo();! sayFoo();! ! // > I am set in defineFoo()

Slide 15

Slide 15 text

foo = "I am a globally-scoped var.";! ! function sayFoo() {! console.log(foo);! }! ! function defineFoo() {! var foo = "I am set in defineFoo()";! }

Slide 16

Slide 16 text

foo = ! function console.log(foo);! } ! function var foo = } var

Slide 17

Slide 17 text

foo = "I am a globally-scoped var.";! ! function sayFoo() {! console.log(foo);! }! ! function defineFoo() {! var foo = "I am set in defineFoo()";! }! ! defineFoo();! sayFoo();! ! // > I am a globally-scoped var.

Slide 18

Slide 18 text

count = 25;! ! function countOccurrences(num) {! num = num || 1;! count += num;! }!

Slide 19

Slide 19 text

count = 25;! ! function countOccurrences(num) {! num = num || 1;! count += num;! }! ! countOccurrences(1);! // > count = 26!

Slide 20

Slide 20 text

// …snip…! countOccurrences(1);! // > count = 26! ! function doSomethingInnocent() {! var vals = [1, 2, 3, 4];! for (i = 0, count = vals.length; i < count; i++) {! console.log(vals[i]);! }! }! doSomethingInnocent();!

Slide 21

Slide 21 text

// …snip…! countOccurrences(1);! // > count = 26! ! function doSomethingInnocent() {! var vals = [1, 2, 3, 4];! for (i = 0, count = vals.length; i < count; i++) {! console.log(vals[i]);! }! }! doSomethingInnocent();! ! countOccurrences(1);! // > count = 5!

Slide 22

Slide 22 text

function console.log(vals }! count = vals.length;

Slide 23

Slide 23 text

// …snip…! countOccurrences(1);! // > count = 26! ! function doSomethingInnocent() {! var vals = [1, 2, 3, 4];! for (var i = 0, count = vals.length; i < count; i++) {! console.log(vals[i]);! }! }! doSomethingInnocent();! ! countOccurrences(1);! // > count = 27!

Slide 24

Slide 24 text

Avoid using global variables inside function scope by declaring them with the var keyword. Takeaway #1

Slide 25

Slide 25 text

Tip Declare all variables at the top of your function. function myFunction(input) {! var i, count;! ! for (i = 0, count = input.length; i < count; i++) {! console.log(input[i]);! }! }!

Slide 26

Slide 26 text

Context 2.

Slide 27

Slide 27 text

this PLEASE EXPLAIN

Slide 28

Slide 28 text

counter++;! }! }!

Slide 29

Slide 29 text

magicCounter = {! count: 0,! increaseCount: function() {! this.count++;! },! decreaseCount: function() {! this.count--;! }! };!

Slide 30

Slide 30 text

magicCounter = {! count: 0,! increaseCount: function() {! this.count++;! },! decreaseCount: function() {! this.count--;! }! };! ! console.log(magicCounter.count); // 0!

Slide 31

Slide 31 text

magicCounter = {! count: 0,! increaseCount: function() {! this.count++;! },! decreaseCount: function() {! this.count--;! }! };! ! console.log(magicCounter.count); // 0! magicCounter.increaseCount();! console.log(magicCounter.count); // 1!

Slide 32

Slide 32 text

magicCounter = {! count: 0,! increaseCount: function() {! this.count++;! },! decreaseCount: function() {! this.count--;! }! };! ! console.log(magicCounter.count); // 0! magicCounter.increaseCount();! console.log(magicCounter.count); // 1! magicCounter.increaseCount();! console.log(magicCounter.count); // 2! !

Slide 33

Slide 33 text

magicCounter = {! count: 0,! increaseCount: function() {! this.count++;! },! decreaseCount: function() {! this.count--;! }! };! ! console.log(magicCounter.count); // 0! magicCounter.increaseCount();! console.log(magicCounter.count); // 1! magicCounter.increaseCount();! console.log(magicCounter.count); // 2! magicCounter.decreaseCount();! console.log(magicCounter.count); // 1!

Slide 34

Slide 34 text

magicCounter.count = 0;! ! myCounterIncreaser = function(callback) {! console.log("Increasing counter.");! callback();! console.log(magicCounter.count);! console.log(this.count);! }!

Slide 35

Slide 35 text

magicCounter.count = 0;! ! myCounterIncreaser = function(callback) {! console.log("Increasing counter.");! callback();! console.log(magicCounter.count);! console.log(this.count);! }! ! myCounterIncreaser(magicCounter.increaseCount);! // > Increasing counter.! // > 0! // > 1!

Slide 36

Slide 36 text

magicCounter.count = 0;! ! myCounterIncreaser = function(callback) {! console.log("Increasing counter.");! callback();! console.log(magicCounter.count);! console.log(this.count);! }! ! myCounterIncreaser(magicCounter.increaseCount);! // > Increasing counter.! // > 0! // > 1! myCounterIncreaser(magicCounter.increaseCount);! // > Increasing counter.! // > 0! // > 2!

Slide 37

Slide 37 text

The this keyword and the context within the function depend entirely on how the function was invoked. Takeaway #2

Slide 38

Slide 38 text

default context

Slide 39

Slide 39 text

function logContext() {! console.log(this);! }! ! logContext();! // > Global!

Slide 40

Slide 40 text

function contextMagic() {! function logContext() {! console.log(this);! }! ! logContext();! }! ! contextMagic();! // > Global!

Slide 41

Slide 41 text

The default context will be the global context for functions invoked by name or variable name within the global context. Takeaway #3

Slide 42

Slide 42 text

method context

Slide 43

Slide 43 text

contextMethod = {! logContext: function() {! console.log(this);! }! };! ! contextMethod.logContext();! // > Object { logContext: [Function] }!

Slide 44

Slide 44 text

contextMethod = logContext: console.log( } ! contextMethod.logContext();! // > Object { logContext: [Function] } var myContextLogger = contextMethod.logContext;! myContextLogger();! // > Global!

Slide 45

Slide 45 text

.call() & .apply()

Slide 46

Slide 46 text

var foo = {! logContext: function() {! console.log(this);! }! };

Slide 47

Slide 47 text

var foo = {! logContext: function() {! console.log(this);! }! };! ! ! foo.logContext();! // > Object { logContext: [Function] }

Slide 48

Slide 48 text

var foo = {! logContext: function() {! console.log(this);! }! };! ! ! foo.logContext();! // > Object { logContext: [Function] } ! ! foo.logContext.call(this);! // > Global

Slide 49

Slide 49 text

var foo = {! logContext: function() {! console.log(this);! }! };! ! var bar = {! baz: "fizz"! };!

Slide 50

Slide 50 text

var foo = {! logContext: function() {! console.log(this);! }! };! ! var bar = {! baz: "fizz"! };! ! foo.logContext();! // > Object { logContext: [Function] } !

Slide 51

Slide 51 text

var foo = {! logContext: function() {! console.log(this);! }! };! ! var bar = {! baz: "fizz"! };! ! foo.logContext();! // > Object { logContext: [Function] } ! ! foo.logContext.call(bar);! // > Object { baz: "fizz" }!

Slide 52

Slide 52 text

Using .call() and .apply() gives you the control you might need over the context inside a function or method. Takeaway #4

Slide 53

Slide 53 text

Objects & Prototypes 3.

Slide 54

Slide 54 text

{}

Slide 55

Slide 55 text

var foo = {! bar: "baz",! fizz: "buzz",! bang: function() {! console.log(this.bar + " " + this.fizz);! }! };!

Slide 56

Slide 56 text

var foo = {! bar: "baz",! fizz: "buzz",! bang: function() {! console.log(this.bar + " " + this.fizz);! }! };! ! foo.bang();! // > baz buzz!

Slide 57

Slide 57 text

prototype chain JavaScript’s complicated inheritance model Object Oriented JavaScript and the

Slide 58

Slide 58 text

name = $name;! }! ! public function sayHello()! {! return "Hello. My name is {$this->name}.";! }! }

Slide 59

Slide 59 text

Slide 60

Slide 60 text

function Person(name) {! this.name = name;! }! ! Person.prototype.sayHello = function() {! return "Hello. My name is " + this.name + ".";! }

Slide 61

Slide 61 text

Tip Use Function.prototype to add methods to your constructor functions for performance reasons.

Slide 62

Slide 62 text

function Person(name) {! this.name = name;! }! ! Person.prototype.sayHello = function() {! return "Hello. My name is " + this.name + ".";! }! ! function Developer(name) {! Person.call(this, name);! }!

Slide 63

Slide 63 text

function Developer(name) {! Person.call(this, name);! }! ! // inherit from Person! Developer.prototype = Object.create(Person.prototype);!

Slide 64

Slide 64 text

function Developer(name) {! Person.call(this, name);! }! ! // inherit from Person! Developer.prototype = Object.create(Person.prototype);! ! // correct the prototype constructor from Person to Developer! Developer.prototype.constructor = Developer;!

Slide 65

Slide 65 text

function Developer(name) {! Person.call(this, name);! }! ! // inherit from Person! Developer.prototype = Object.create(Person.prototype);! ! // correct the prototype constructor from Person to Developer! Developer.prototype.constructor = Developer;! ! // override the sayHello method of Person for Developers! Developer.prototype.sayHello = function() {! return Person.prototype.sayHello.call(this) ! + " I am a developer.";! }!

Slide 66

Slide 66 text

var p = new Person('PersonGuy');! var d = new Developer('DeveloperGal');!

Slide 67

Slide 67 text

var p = new Person('PersonGuy');! var d = new Developer('DeveloperGal');! ! console.log(p.sayHello());! // > Hello. My name is PersonGuy.!

Slide 68

Slide 68 text

var p = new Person('PersonGuy');! var d = new Developer('DeveloperGal');! ! console.log(p.sayHello());! // > Hello. My name is PersonGuy.! console.log(d.sayHello());! // > Hello. My name is DeveloperGal. I am a developer.!

Slide 69

Slide 69 text

var p = new Person('PersonGuy');! var d = new Developer('DeveloperGal');! ! console.log(p.sayHello());! // > Hello. My name is PersonGuy.! console.log(d.sayHello());! // > Hello. My name is DeveloperGal. I am a developer.! ! console.log(p instanceof Person);! // > true!

Slide 70

Slide 70 text

var p = new Person('PersonGuy');! var d = new Developer('DeveloperGal');! ! console.log(p.sayHello());! // > Hello. My name is PersonGuy.! console.log(d.sayHello());! // > Hello. My name is DeveloperGal. I am a developer.! ! console.log(p instanceof Person);! // > true! console.log(p instanceof Developer);! // > false!

Slide 71

Slide 71 text

var p = new Person('PersonGuy');! var d = new Developer('DeveloperGal');! ! console.log(p.sayHello());! // > Hello. My name is PersonGuy.! console.log(d.sayHello());! // > Hello. My name is DeveloperGal. I am a developer.! ! console.log(p instanceof Person);! // > true! console.log(p instanceof Developer);! // > false! ! console.log(d instanceof Developer);! // > true!

Slide 72

Slide 72 text

var p = new Person('PersonGuy');! var d = new Developer('DeveloperGal');! ! console.log(p.sayHello());! // > Hello. My name is PersonGuy.! console.log(d.sayHello());! // > Hello. My name is DeveloperGal. I am a developer.! ! console.log(p instanceof Person);! // > true! console.log(p instanceof Developer);! // > false! ! console.log(d instanceof Developer);! // > true! console.log(d instanceof Person);! // > true!

Slide 73

Slide 73 text

Tip For more information on OOP JS, visit the Mozilla Developer Zone article at http://crth.net/mdnoopjs

Slide 74

Slide 74 text

Object oriented development in JavaScript requires an understanding of the prototype. Takeaway #5

Slide 75

Slide 75 text

Resources 4.

Slide 76

Slide 76 text

JavaScript Essential Reading List http://crth.net/jsreading

Slide 77

Slide 77 text

WatchMeCode.net JavaScript Fundamentals http://crth.net/jsfundamentals

Slide 78

Slide 78 text

https://github.com/getify/You-Dont-Know-JS You Don’t Know JS Series

Slide 79

Slide 79 text

Recap 5. All Objects have a prototype through which we can accomplish inheritance in JS. 1. Avoid using global vars inside function scope. 2. Context and this depend on invocation. 3. Default context is the global context. 4. .call() and .apply() gives you control over the context.

Slide 80

Slide 80 text

JEFF CAROUTH DEVELOPER AT LIFTOPIA @jcarouth [email protected] Freenode: #phpmentoring 50% of Loosely Coupled

Slide 81

Slide 81 text

Thank You joind.in/10647 @jcarouth