Don't like this style? Click here to change it! blue.css
We've been hinting at "Object-Oriented" JavaScript in our chats. Today I want to give you the tools to create that paradigm for your code. But I also want to encourage you not to be too dogmatic about what that means. Instead understand the precise way that this tool (JS) works and then let your desire for extensible, modular, and flexible code guide your search for useful design patterns.
For those in the mood for self-direction try running through these starting at a topic which sounds good to you: http://ejohn.org/apps/learn
Other references for today:
As wrap up for our DOM discussions here is how to add elements to a page programmatically:
JS Bin on jsbin.comStrike Task 1: Create a CSS class which adds a strike-through effect. Now create a click listener on my family members that toggles your strike class. I want you to be able to click to strike and click again to unstrike.
Baby Task 2: Create an input box and button so that a new family member can be added to the list. Make sure that the new family member is strikable too.
this
(function context)Everything is an object in JS, objects are your friends, objects are your enemies. So a lot of what you want to do as an aspiring javascript engineer is to control which objects get which methods and properties. You know: construction, inheritance, composition, and access-control (private/public/friend).
Step one is understanding the object pronoun this
. Inside any function the this
keyword is an alias of the invoking object (default is window
).
Here is an object holding some state using this
(not really an instance of a class yet):
Now we can share functions between objects and this
will work in that beautiful pronoun-y way:
Console This Task 3: Take that example and console.log(this)
in
toString()
. Edit goUndercover
to only alter the appearance of aPerson
.
apply/call
So the first snafu to fix is being able to call a method and set the this to whatever you want. There are two, nearly identical, options in JavaScript:
funcname.apply(new_this, [arg1, arg2, …])
funcname.call(new_this, arg1, arg2, …)
The only difference is that apply takes an array of arguments and call expects a comma separated list of arguments (and it is a little faster).
The real win is being able to set the "context" of any method to what you want.
JS Bin on jsbin.comPseudo-Array Trace Task 4: Explain that snippet to a neighbor.
Borrowing Utilities Task 5: I love Array.prototype.forEach
which we
used yesterday (we'll talk prototypes in a bit). Use Array.prototype.forEach.call
to use this
functionality on each character of a string. (Come up with your own character manipulating function.)
bind
Bind is a method of all functions which sets this
and returns a function which is ready to use (as
opposed to apply/call which execute the function).
Undercover Task 6: Use bind to adjust our undercover function so that
fido.goUndercover
actually changes aPerson
instead.
A common use case of bind
is callback functions.
Fix It Task 7: Fix the above snippet by using bind
. (Hint: inspect
the id of the input box after the first blur.)
arguments
Functions also have an arguments
object which can be manipulated in fun ways. (docs here
)
The above call trick is often combined with Array.prototype.splice
to convert the arguments object
into an arguments array.
Arbitrary Average Task 8: Write a function which can take in an arbitrary number of numbers and which returns the average of those numbers. Bonus for requiring at least 1 argument.
Now the real fun of objects and classes (IMHO) is making whole swarms of things which interact in ways that I can't predict (emergent chaos). To do THAT we need to do more than just make solitary objects but instead classes that spawn clones.
new/Object.create
So making an object is straight forward but a little hard to spawn with. The ES5 way (ES6 provided native classes (see docs above)) uses functions. All functions can be seen as constructors.
I'm running out of time to write this so head to our book and read: The Constructor Pattern. Then research/solve the following:
New vs. Create Task 9: Look for the key differences between
Object.create
and new
FunctionNameHere()
. Use both to create a family of people from a Person class you design. (Look at the
1.2.3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
)
prototype
When you use the above techniques to create instances you set the prototype
of your instances. In
Javascript when you look up an attribute/method/key on an object it checks first with the object then with that
object's prototype. It goes up the prototype chain until it finds the property somewhere. You can alter the
prototype of an object or reference it directly. You can also access the constructor
.
Over-ride Task 10: Create a class which has the method
describe_yourself
. Create two instances of that class, override the method on one but not the other.
Confirm they are different.
Inheritance Task 11: Create a Poodle class which inherits from a Dog class following the pattern found here.