WebFund 2014W Lecture 5
Video
Video from the lecture given on Jan 22, 2014 is now available from multiple sources:
- small at screencast.com (flash/mp4)
- large at screencast.com (flash/mp4)
- original at CUOL (mp4)
- original at homeostasis (mp4)
Lecture Notes
In this lecture JavaScript object inheritance (the prototype object) is explained. Along with this an overview of Tutorial 3 is given which covers sessions, cookies, and some other related material. Miscellaneous comments and questions asked throughout the class are also present, and are listed in the last section.
Prototypal Inheritance in JavaScript
Inheritance in JavaScript is not 'classical' as in other languages such as Python, Java, or C/C++. Instead, each object has a hidden prototype object [[Prototype]]
which is inherited from the parent object's visible .prototype
object. By 'hidden', we mean that the object cannot be accessed directly; variables and functions defined in the hidden prototype object are returned if they are accessed/called but haven't been set on the inheriting object. Likewise, by 'visible', we mean that the prototype object appears as a property of the object, with properties which can both be set and used.
There are a lot of explanations of how this works on both stackoverflow, and just generally on the internet. Using the car example as in the lecture, we'll first define the constructor using object literal syntax. Then, we'll do some experiments and see what happens. Note that the examples shown below were done in the developer console on Google Chrome Browser version 32.00.
> var Car = function () { this.speed = 'slow' }; undefined > Car.prototype = {color: 'white'}; Object {color: "white"} > var tesla = new Car(); undefined > tesla Car {speed: "slow", color: "white"} > tesla.prototype undefined > tesla.hasOwnProperty('color'); false > tesla.hasOwnProperty('speed'); true
Notice how tesla.prototype
does not exist. When tesla
is created as a Car
object, it's properties are augmented by the properties in Car.prototype
. Looking closer, we also see that the JavaScript runtime in the Chrome browser 'cheats' by telling us that color
is a property of the variable tesla
. Using the hasOwnProperty
function1 however, we see that color
is actually a property of tesla
's prototype. Shown below is the same example using the Object.create
function2, as it was done during class.
> var car = {'color': 'white'}; undefined > car Object {color: "white"} > var tesla = Object.create(car); undefined > tesla.speed = 'slow'; "slow" > tesla.prototype undefined > tesla.hasOwnProperty('color'); false > tesla.hasOwnProperty('speed'); true
Object.create
creates a new object, sets its prototype to the passed in argument, and then returns that object. So in order to actually create the same object as we did in the previous example any variables set in the prototype there would actually have to be set in the car object here. Note that instead of setting the speed
of tesla
to slow
after creation, it can be supplied in the call to Object.create
.
As we're learning JavaScript, some good reference material would be Douglas Crockford's book 'JavasScript; The Good Parts', as well as his posted videos on the yuiblog site.
Tutorial 3 Overview
For this tutorial and any consecutive tutorials the node_modules
folder will be provided with the demo code. Otherwise, modules can be downloaded/installed using the node package manager (npm
command) which is installed with node.
The tutorial consists of a demo application which simulates a basic login process, complete with cookie-based sessions. The basic flow is as follows: when a user logs in the server will set some cookies via the response which is sent back to the browser. Once this occurs the cookies will be sent with every request & response until they expire. For most cookies this is either when the browser closes, or when a certain length of time has passed. Dealing with these cookies is done by middleware which is set in the app.js
file, as shown below.
25 app.use(express.cookieParser('COMP2406 rules!')); 26 app.use(express.session());
For our purposes, all interaction is done with the request's session object (req.session
) during routing. An example of this is shown in index.js
, where we test the session object for a username
. If the username
exists then we know that we have previously logged the user in, so we render the page. Otherwise, we redirect them to the home page. When viewing this process from the developer console in either Firefox or Chrome (or another browser), we'll see http status codes associated with the requests; either a 200 OK
or a 302 Moved Temporarily
.
13 function users(req, res) { 14 if (req.session.username) { 15 res.render("account.jade", {username:req.session.username, 16 title:"Account", 17 loggedInUsers: loggedInUsers}); 18 } else { 19 res.redirect("/?error=Not Logged In"); 20 } 21 };
Not only the status codes are shown in the developer's console. Also shown is more information about any requests; header information (including the user agent string), form/query parameters, cookies, and the actual content of responses.
The above code snippet also shows us something about Jade. Put simply, it's a template engine; it takes template code and transforms it into html. What's even more impressive is that we can pass variables to the templates which will be inserted onto the pages when this transformation occurs. This is shown on line 15
by the call to res.render
where we pass in the template file followed by an object of variables.
One last thing which should be also be mentioned is session hijacking. Consider the situation that we have, where login information is stored in the cookies. If an adversary was able to guess how our cookies were constructed, then they would be able to fake being a user, and would gain access to the user's account. To help protect against this the express session module employs cryptographic hashing in order to obfuscate cookies. This type of hashing can't be reversed, so validity is checked through a re-hashing of supplied data which is compared to an existing hash.
Miscellaneous
- How do we start node?
- Different linux distributions may call the package different names. The two most common are
node
, andnodejs
.
- What's the difference between the prototype property and the object's prototype.
- An object's prototype property is just that, a property named
prototype
. When that object is used as the base class for another object however, the new object will have the hidden[[Prototype]]
property set as the base classes.prototype
property. See this StackOverflow answer for more information.
- What's the deal with equality predicates? Which ones should I be using?
- Whenever you're able to, use
a === b
instead ofa == b
, etc. The double equals is able to carry out type coercion, which may be an unintended side effect. In addition to this, there are other small differences in equality checking.
- Is there another way to set the object prototype?
- There are a few ways, which are all listed on this page in the Mozilla Developer Network Javascript Guide!
- The Comp 2406 virtual machine isn't running well on my machine!
- Well, check out the video lectures starting with this one; if the VM is running slower than the one in class then odds are that your computer is misconfigured.