# 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 |
댓글