Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaScript's Difficult Concepts Explained

JavaScript's Difficult Concepts Explained

When approaching JavaScript as a PHP developer some of the nuances of the language take a while to become comfortable. If you've ever wondered how context and the this keyword work, when to declare a variable, how to create objects and use prototypes in JavaScript, you are not alone. These concepts seems crazy at first, but with some examples you can grasp and use them in your code today. This session will cover the finer points of JavaScript the language from the perspective of someone who is proficient with PHP or another language.

Jeff Carouth

June 29, 2013
Tweet

More Decks by Jeff Carouth

Other Decks in Programming

Transcript

  1. reducing the wat-factor when PHPers write JS JavaScript’s Difficult Concepts

    Explained Jeff Carouth // @jcarouth // #lsp13 Saturday, June 29, 13
  2. foo = "I am a globally-scoped var."; console.log(foo); // >

    I am a globally-scoped var. Saturday, June 29, 13
  3. foo = "I am a globally-scoped var."; function sayFoo() {

    console.log(foo); } sayFoo(); // > I am a globally-scoped var. Saturday, June 29, 13
  4. 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() Saturday, June 29, 13
  5. count = 25; function countOccurrences(num) { num = num ||

    1; count += num; } function doSomethingInnocent() { var vals = [1, 2, 3, 4]; for (i = 0, count = vals.length; i < count; i++) { console.log(vals[i]); } } countOccurrences(1); // > count = 26 doSomethingInnocent(); // > count = 4 Saturday, June 29, 13
  6. 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. Saturday, June 29, 13
  7. Avoid using global variables inside function scope by declaring them

    with the var keyword. Takeaway #1 Saturday, June 29, 13
  8. 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]); } } Saturday, June 29, 13
  9. <?php class Example { private $counter; private $closed; public function

    doSomethingMagic() { $this->counter = 5; $this->doSomethingElse(); } public function doSomethingElse() { // do something } } Saturday, June 29, 13
  10. magicCounter = { count: 0, increaseCount: function() { this.count++; },

    decreaseCount: function() { this.count--; } }; console.log(magicCounter.count); // 0 magicCounter.increaseCount(); magicCounter.increaseCount(); console.log(magicCounter.count); // 2 magicCounter.decreaseCount(); console.log(magicCounter.count); // 1 Saturday, June 29, 13
  11. count = 0; magicCounter.count = 0; myCounterIncreaser = function(callback) {

    console.log("Increasing counter."); callback(); callback(); console.log(magicCounter.count); // 0 console.log(this.count); // 2 } myCounterIncreaser(magicCounter.increaseCount); // > Increasing counter. // > 0 // > 2 Saturday, June 29, 13
  12. The this keyword and the context of the function depend

    entirely on how the function was invoked. Takeaway #2 Saturday, June 29, 13
  13. The default context will be the global context for functions

    invoked by name or variable name within the global context. Takeaway #3 Saturday, June 29, 13
  14. contextMethod = { logContext: function() { console.log(this); } }; contextMethod.logContext();

    // > Object { logContext: [Function] } Saturday, June 29, 13
  15. contextMethod = { logContext: function() { console.log(this); } }; contextMethod.logContext();

    // > Object { logContext: [Function] } var myContextLogger = contextMethod.logContext; myContextLogger(); // > Global Saturday, June 29, 13
  16. var foo = { logContext: function() { console.log(this); } };

    foo.logContext(); // > Object { logContext: [Function] } foo.logContext.call(this); // > Global Saturday, June 29, 13
  17. var foo = { logContext: function() { console.log(this); } };

    var bar = { baz: "fizz" }; foo.logContext(); // > Object { logContext: [Function] } foo.logContext.call(bar); // > Object { baz: "fizz" } Saturday, June 29, 13
  18. Using .call() and .apply() gives you the control you might

    need over the context inside a function or method. Takeaway #4 Saturday, June 29, 13
  19. var foo = { bar: "baz", fizz: "buzz", bang: function()

    { console.log(this.bar + " " + this.fizz); } }; foo.bang(); // > baz buzz Saturday, June 29, 13
  20. Tip Use Function.prototype to add methods to your constructor functions

    for performance reasons. Saturday, June 29, 13
  21. function Person() {} Person.prototype.sayHello = function() { console.log("Hello, I am

    a person."); } function Developer() { Person.call(this); } Saturday, June 29, 13
  22. function Developer() { Person.call(this); } // inherit from Person Developer.prototype

    = Object.create(Person.prototype); Saturday, June 29, 13
  23. function Developer() { Person.call(this); } // inherit from Person Developer.prototype

    = Object.create(Person.prototype); // correct the prototype constructor from Person to Developer Developer.prototype.constructor = Developer; Saturday, June 29, 13
  24. function Developer() { Person.call(this); } // 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 from Person Developer.prototype.sayHello = function() { console.log('Hello, I am a developer.'); } Saturday, June 29, 13
  25. var myDeveloper = new Developer(); myDeveloper.sayHello(); // > "Hello, I

    am a developer." myDeveloper instanceof Developer // true myDeveloper instanceof Person //true Saturday, June 29, 13
  26. Tip For more information on OOP JS, visit the Mozilla

    Developer Zone article at http://crth.net/mdnoopjs Saturday, June 29, 13
  27. Recap 5. All Objects have a prototype. 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. Saturday, June 29, 13