this
.training
, for your work.npm install
.Suppose we have the following object literal:
{
foo: 'bar',
baz: function () {
// How do I access the value stored in 'foo' above?
}
}
foo
and baz
are both properties, also known as keys. We typically use
the term "keys" when object literals are used as dictionaries. When we mix data
and methods, we should prefer the term "object" over "dictionary". So, we'll
also call the accessor name a "property" instead of a "key".
foo
is a kind of property known as an attribute. Attributes are properties
that point to values. On the other hand, properties that point to functions are
methods.
For the remainder of this talk, we will be focusing exclusively on how we can
use this
inside of a method to point to value defined elsewhere in an object
literal. All other uses of this
are out-of-scope.
The answer to the question posed in the previous code snippet is that we use
this
to refer to the object's own properties. That is to say, when we use
this
inside a method, that method is contained within an object. For the
patterns used in this talk, the containing object is what this
refers to.
{
foo: 'bar',
baz: function () {
return this.foo;
}
}
Do not over-generalize. We usually cannot know what this
refers to until
the code runs.
this
One way to break up the complexity of a problem is by using multiple kinds of objects together, and having each object be responsible for representing a small part of the problem. But these objects don't need to exist in isolation - objects can have other objects (or even collections of other objects) as properties.
Suppose that we wanted to create a simple program ('RunTracker') that helps people prepare for running a 5k. Each day that a person runs, they create a record of their run which contains:
The program also stores information about the user (the user's name and email address) and can perform some calculations (total distance run, longest run so far, and average speed).
Using the description of the program above, create an entity diagram.
this
let user = {
name: "Person McFace",
email: "wdi@personmcface.com",
runs : [
{
date: "2016-05-25 15:00",
distance: 1200,
timeTaken: 600
},
{
date: "2016-05-25 15:00",
distance: 1400,
timeTaken: 800
}
],
totalDistance : function () {},
longestRun : function () {},
averageSpeed : function () {}
}
When we start thinking about how the methods for 'User' will work, we run into a difficulty. A method for calculating the longest run so far needs to be able to see, and refer to, all of the runs associated with that particular user. How do we do that?
Follow along as I demonstrate how to complete writing each method.
In groups, you're going to work on a similar program to our previous one, this time for meal tracking. In particular, you're going to create an example 'User' object, complete with several 'Meals'.
A 'User' needs to have:
name
)bornOn
)calorieTarget
)meals
)Every 'Meal' must have:
title
), e.g. 'breakfast', 'lunch', 'dinner'date
), represented as a string e.g. "2016-06-25"description
)calories
)Then, create the following methods for your instance of a 'User':
caloriesEatenOn
, which accepts a date (in the format above) and calculates
the total number of calories consumed on that date.avgDailyCalories
, which (as indicated), calculates the average number of
calories consumed per day, rounded down to the nearest whole calorie.onTrack
, which compares averageDailyCalories to the User's target daily
calorie intake, and returns true
if average caloric intake is at or below
the target (or false
if the reverse is true).Add your code to lib/meals.js
, structured similarly to
lib/runs.js
.