Describe the following object oriented programming concepts: →
In Java, what language features / constructs allow inheritance, polymorphism, encapsulation, and abstraction? →
Although JavaScript has objects, its approach to object-oriented programming is a bit unconventional.
First off, in both Node and browser-based JavaScript implementations a global object exists:
global
for nodewindow
for browsers
Let's see what this looks like by: →
const
, let
, and var
)
console.log(global.mistake);
function oopsGlobal() {
mistake = "yup";
}
oopsGlobal();
console.log(mistake);
console.log(global.mistake);
Methods are object properties that are functions (a function within the context of an object).
const cat = {};
cat.speak = function() {
console.log("meow");
};
cat.speak();
Notice that you can attach methods to any arbitrary object instance! (???)
"When a function is called as a method—looked up as a property and immediately called, as in object.method()—the special constiable this
in its body will point to the object that it was called on". What will be printed out in the code below?. →
function speak() {
if(this.nationality == "Japanese") {
console.log("nyan");
} else if (this.nationality == "American") {
console.log("meow");
} else {
console.log("default cat noise");
}
}
const japaneseCat = {nationality:"Japanese", speak:speak};
const americanCat = {nationality:"American", speak:speak};
japaneseCat.speak();
americanCat.speak();
nyan
meow
this
refers to the object that the method was called onA standalone function's this
refers to the global object. What will the following code print out? →
global.outside = 5;
const f = function() {
console.log(this.outside);
}
f();
5
// this is the global object!
Aaaand… what's the output of our speak function from the previous slide if we call it on its on (not within the context of an object)? →
function speak() {
if(this.nationality == "Japanese") {
console.log("nyan");
} else if (this.nationality == "American") {
console.log("meow");
} else {
console.log("default cat noise");
}
}
speak();
default cat noise
console.log(this.nationality)
… we'll see it's undefined
undefined
this
refers to the global objectBesides method invocation and regular function invocation, what are two other ways of executing a function? →
call
- invoke function that call was called on with specified this
and positional argumentsapply
- invoke function that apply was called on with specified this
and an Array
containing positional arguments
When invoking a function with call
or apply
:
this
will be bound to the value passed in as the first argument.
function greet(person) { console.log(this.greeting, person); }
const obj = { greeting: 'hi' };
greet.call(obj, 'joe');
hi joe
Aaaand… of course, call and apply with our cat example (modified a bit). What is the output of this code? →
function speak(how, toWho) {
const d = {Japanese: "nyans", American: "meows"};
const noise = d[this.nationality] || "default cat noise";
console.log(noise, how, 'at', toWho);
}
const cat = {nationality: "American"}
speak.apply(cat, ['loudly', 'you']);
speak.apply({}, ['softly', 'me']);
meows loudly at you
default cat noise softly at me
call
or apply
, this
refers to the object passed in as the first argument to either methodWhat is the output of this code and why? →
const counter = {numbers: [1, 2, 3, 4], animal:'owl'};
counter.count = function() {
this.numbers.forEach(function(n) {
console.log(n, this.animal + (n > 1 ? 's' : ''));
});
};
counter.count();
1 'undefined'
2 'undefineds'
3 'undefineds'
4 'undefineds'
The anonymous function is being invoked as a regular function for every element in the Array
, counter.numbers
. this
refers to global object, which does not have the property, animal
, resulting in undefined
.
In previous slides, we said that the this
value in arrow functions is the this
in the scope that the arrow function was created in (that is, it doesn't have it's own this
, it just uses the one that's already there!
Let's see how this works: →
const counter = {numbers: [1, 2, 3, 4], animal:'owl'};
counter.count = function() {
this.numbers.forEach((n) => {
console.log(n, this.animal + (n > 1 ? 's' : ''));
});
};
counter.count();
1 'owl'
2 'owls'
3 'owls'
4 'owls'
Better! this
is whatever this
refers to in the count method, and because count
was invoked as a method, this
is the object that count
was called on.
Of course, that means if we use the following code, what will this
refer to? What is the output of the following code? →
function foo() {
const bar = (x) => { console.log(this.qux); };
bar();
}
foo();
undefined
this
references this
in the function, foo
, which was invoked as a regular function. Consequently, this
is the global object.
What is this?????
this
is the global objectthis
is the object the method was called onthis
is the first argument passed in to call or applythis
is this
from the enclosing contextLet's try running this code… →
empty
?
const empty = {};
console.log(empty.toString);
console.log(empty.toString());
[Function: toString]
[object Object]
Magic!
If we started off with an empty object in the previous slide, where did the toString method come from?