본문 바로가기

Advanced Javascript

web/javascript by 낼스 2019. 7. 16.

00033.js_advanced-js-1223050832337995-8.ppt
4.45MB

# JavaScript data types
    Primitive               and                 objects
        number
        string
        boolean
        undefined
        null

# Object literal notation
    ● { Wrapped in curly braces }
    ● ,-delimited properties
    ● key:value pairs
    ● var obj = {a: 1, "b c d": 2};

# Array literal notation
    var array = [
      "Square", "brackets",
      "wrap", "the",
      "comma-delimited",
      "elements"
    ];

# JSON
    ● JavaScript Object Notation
    ● Uses object and array literals
    ● Quotes required for properties
    ● {"num": 1, "str": "abc", "arr": [1,2,3]}

# Functions
    ● functions are objects
    ● they have properties
    ● they have methods
    ● can de copied, deleted, augmented...
    ● special feature: invokable

    function boo(what) {
      return what;
    }
    or
    var boo = function(what) {
      return what;
    };

    function boo(what) {
      return what;
    }
    or
    var boo = function bootoo(what) {
      return what;
    };

    >>> boo.length
    1
    >>> boo.name
    "bootoo"

    >>> var foo = boo;
    >>> foo("doodles")
    "doodles"
    >>> foo.call(null, "moo!");
    "moo!"

# Constructors
    ● when invoked with new, functions return an object known as this
    ● you have a chance of modifying this before it's returned
    ● you can also return some other object

# Constructor functions
    var Person = function(name) {
      this.name = name;
      this.speaks = 'fr';
      this.say = function() {
        return "Je m'appelle " + this.name;
      };
    };

    >>> var julien = new Person("Julien");
    >>> julien.say();
    "Je m'appelle Julien"

# constructor property
    >>> function Person(){};
    >>> var jo = new Person();
    >>> jo.constructor === Person
    true

    >>> var o = {};
    >>> o.constructor === Object
    true
    >>> [1,2].constructor === Array
    true

# Built-in constructor functions
    ● Object
    ● Array
    ● Function
    ● RegExp
    ● Number
    ● String
    ● Boolean
    ● Date
    ● Error, SyntaxError, ReferenceError…

# Wrapper objects vs. primitive
    >>> typeof new Number(1)
    "object"
    >>> typeof 1
    "number"

# prototype
    a property of the function objects

    >>> var boo = function(){};
    >>> typeof boo.prototype
    "object"
# Prototypes can be augmented
    >>> boo.prototype.a = 1;
    >>> boo.prototype.sayAh = function(){};

# Prototypes can be overwritten
    >>> boo.prototype = {a: 1, b: 2};

# How is the prototype used?
    when a function is invoked as a constructor

    var Person = function(name) {
      this.name = name;
    };
    Person.prototype.say = function() {
      return this.name;
    }

    >>> var dude = new Person('dude');
    >>> dude.name;
    "dude"
    >>> dude.say();
    "dude"

    say() is a property of the prototype object
    but it behaves as if it's a property of the dude object

    can we tell the difference?

# Own properties vs. prototype’s
    >>> dude.hasOwnProperty('name');
    true
    >>> dude.hasOwnProperty('say');
    false

# isPrototypeOf()
    >>> Person.prototype.isPrototypeOf(dude);
    true
    >>> Object.prototype.isPrototypeOf(dude);
    true

# __proto__

    ● I, the dude, have a secret link to the prototype of
    the constructor that created me

    ● __proto__ is not directly exposed in all browsers

    >>> dude.__proto__.hasOwnProperty('say')
    true
    >>> dude.prototype
    ??? // Trick question
    >>> dude.__proto__.__proto__.hasOwnProperty('toString')
    true

# Inheritance via the prototype
    >>> var Dad = function(){this.family = "Stefanov";};
    >>> var Kid = function(){};
    >>> Kid.prototype = new Dad();
    >>> var billy = new Kid();
    >>> billy.family
    "Stefanov"

# Inherit one more time
    >>> var GrandKid = function(){};
    >>> GrandKid.prototype = billy;
    >>> var jill = new GrandKid();
    >>> jill.family
    "Stefanov"

# Inheritance…
    >>> jill.hasOwnProperty('family')
    false
    >>> jill.__proto__.hasOwnProperty('family')
    false
    >>> jill.__proto__.__proto__.hasOwnProperty('family')
    true

    >>> billy.family = 'Idol';
    >>> jill.family;
    'Idol'
    >>> jill.__proto__.hasOwnProperty('family');
    true

    >>> delete billy.family;
    >>> jill.family;
    'Stefanov'

# Side effect…
    >>> billy.constructor === Kid
    false
    >>> billy.constructor === Dad
    true

# Side effect… easy to solve
    reset after inheritance

    >>> Kid.prototype.constructor = Kid;
    >>> GrandKid.prototype.constructor = GrandKid;

# isPrototypeOf
    >>> billy.isPrototypeOf(jill)
    true
    >>> Kid.prototype.isPrototypeOf(jill)
    true

# instanceof
    >>> jill instanceof GrandKid
    true
    >>> jill instanceof Kid
    true
    >>> jill instanceof Dad
    true

# Classes?
    ● There are no classes in JavaScript
    ● Objects inherit from objects
    ● classical inheritance is when we think of constructors as if they were classes

# Classical inheritance
    function Parent(){this.name = 'parent';}
    Parent.prototype.getName = function(){   return this.name; };
    function Child(){}
    inherit(Child, Parent);

    - Option 1
        function inherit(C, P) {
          C.prototype = new P();
        }

    - Option 2
        function inherit(C, P) {
          C.prototype = P.prototype;
        }

    - Option 3
        function inherit(C, P) {
          var F = function(){};
          F.prototype = P.prototype;
          C.prototype = new F();
        }

    - Option 3 + super
        function inherit(C, P) {
          var F = function(){};
          F.prototype = P.prototype;
          C.prototype = new F();
          C.super = P.prototype;
        }

    - Option 3 + super + constructor reset
        function inherit(C, P) {
          var F = function(){};
          F.prototype = P.prototype;
          C.prototype = new F();
          C.super = P.prototype; // super
          C.prototype.constructor = C; // reset
        }

# Inheritance by copying properties
    After all, inheritance is all about code reuse
    function extend(parent) {
      var i, child = {};
      for (i in parent) {
        child[i] = parent[i];
      }
      return child;
    }

# Inheritance by copying…
    >>> var parent = {a: 1};
    >>> var child = extend(parent);
    >>> child.a
    1

# Inheritance by copying…
    ● This was a shallow copy
    ● you can make a deep copy using recursion
    ● mixins / multiple inheritance

# Prototypal inheritance
    ● as suggested by Douglas Crockford
    ● no class-like constructors involved
    ● objects inherit from objects
    ● via the prototype

# Prototypal inheritance
    function object(o) {
      function F(){}
      F.prototype = o;
      return new F();
    }

    >>> var parent = {a: 1};
    >>> var child = object(parent);
    >>> child.a;
    1
    >>> child.hasOwnProperty(a);
    false

# No block scope
    >>> if (true) {var inside_block = 1;}
    >>> inside_block
    1

# Function scope
    function boo() {
      var inboo = true;
    }

# Global namespace
    ● every variable is global unless it's in a function and is declared with var
    ● global namespace should be kept clean to avoid naming collisions
    ● function scope can help

# Self-executable functions for  one-off tasks
    (function(){
       var a = 1;
       var b = 2;
       alert(a + b);
    })()

# Closure example #1
    function outer(){
      var local = 1;
      return function(){
        return local;
      };
    }
    - Closure example #1
        >>> var inner = outer()
        >>> inner()
        1

    - Closure example #2
        var inner;
        function outer(){
          var local = 1;
          inner = function(){
            return local;
          };
        }

        >>> typeof inner
        "undefined"
        >>> outer()
        >>> inner()
        1

    - Closure example #3

        function makePlus(arg) {
          var n = function(){
            return arg;
          };
          arg++;
          return n;
        }

        >>> var getValue = makePlus(1234);
        >>> getValue()
        1235

    - Closure #4 – in a loop
        function make() {
          var i, a = [];
          for(i = 0; i < 3; i++) {
            a[i] = function(){
              return i;
            }
          }
          return a;
        }
        >>> var funcs = make();
        >>> funcs[0]();
        3
        >>> funcs[1]();
        3
        >>> funcs[2]();
        3

    - Closure #4 – corrected
        function make() {
          var i, a = [];
          for(i = 0; i < 3; i++) {
            a[i] = (function(local){
              return function(){return local;}
            })(i)
          }
          return a;
        }

# Getter/Setter
    var getValue, setValue;
    (function() {
      var secret = 0;
      getValue = function(){
        return secret;
      };
      setValue = function(v){
        secret = v;
      };
    })()

    // usage
    >>> getValue()
    0
    >>> setValue(123)
    >>> getValue()
    123

# Iterator
    function setup(x) {
      var i = 0;
      return function(){
        return x[i++];
      };
    }

    >>> var next = setup(['a', 'b', 'c']);
    >>> next()
    'a'
    >>> next()
    'b'

# Loop through DOM elements - wrong
    // all elements will alert 5
    for (var i = 1; i < 5; i++ ){
      document.getElementById('btn'+i).onclick =
        function(){
          alert(i);
        };
    }

# Loop through DOM elements - correct
    // first element alerts 1, second 2,...
    for (var i = 1; i < 5; i++ ){
      document.getElementById('btn'+i).onclick =
        (function(i){
          return function(){alert(i);};
        })(i)
    }

# Wrapping up…
    How to tell what’s going on?
    typeof, instanceof, isPrototypeOf()…

    >>> typeof variable
    ● typeof is an operator, not a function
    ● Not typeof(variable) even if it works
    ● Returns a string, one of:
      "string", "number", "boolean",
      "undefined", "object", "function"

# typeof
    if (typeof whatever === "undefined") {
      // whatever is not defined
    }
    if (whatever == undefined) {
      // hmm, not so sure
    }

# >>> obj instanceof MyConstructor
    ● Not instanceof()
    ● Returns true | false
    ● true for all constructors up the chain

    >>> obj.constructor
    ● Points to the constructor function used to create this obj

    >>> obj.isPrototypeOf(child_obj)
    ● Respects the prototype chain

    >>> obj.hasOwnProperty("prop")
    ● Own properties vs. properties of the prototype

# obj.propertyIsEnumerable("prop")
    ● Will it show up in a for-in loop
    ● Caution: enumerable properties of the prototype
      will return false but still show up in the for-in loop

# Objects
    ● JavaScript has a few primitive types,
      everything else is an object
    ● Objects are hashes
    ● Arrays are objects

# Functions
    ● Functions are objects, only invokable
    ● call() and apply() methods
    ● prototype property

# Prototype
    ● Functions have a prototype property which is an object
    ● Useful with Constructor functions

# Constructor
    ● A function meant to be called with new
    ● Returns an object

# Class
    No such thing in JavaScript

#Inheritance
    ● Prototypal
    ● Classical
        … and approximately 101 other ways and variations

# Scope
    ● Lexical function scope

# Closure
    When a variable leaves its function scope

'web > javascript' 카테고리의 다른 글

d3js - enter(), update() and exit()  (0) 2019.07.16
Javascript Slider  (0) 2019.07.16
change element readonly & disabled to double click~~!!  (0) 2019.07.16
d3 enter  (0) 2019.07.15
ReactJS  (0) 2019.07.15

댓글