diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json
index 85c5cdc94b2..0e2c50c358a 100644
--- a/seed/challenges/object-oriented-and-functional-programming.json
+++ b/seed/challenges/object-oriented-and-functional-programming.json
@@ -20,9 +20,9 @@
"Give your motorBike
object a wheels
, engines
and seats
attribute and set them to numbers."
],
"tests":[
- "assert(typeof(motorBike.engines) === 'number', 'message: motorBike
should have a engines
attribute set to a number.');",
- "assert(typeof(motorBike.wheels) === 'number', 'message: motorBike
should have a wheels
attribute set to a number.');",
- "assert(typeof(motorBike.seats) === 'number', 'message: motorBike
should have a seats
attribute set to a number.');"
+ "assert(typeof motorBike.engines === 'number', 'message: motorBike
should have a engines
attribute set to a number.');",
+ "assert(typeof motorBike.wheels === 'number', 'message: motorBike
should have a wheels
attribute set to a number.');",
+ "assert(typeof motorBike.seats === 'number', 'message: motorBike
should have a seats
attribute set to a number.');"
],
"challengeSeed":[
"var car = {",
@@ -39,12 +39,15 @@
"",
" // Only change code above this line.",
"",
- "};",
- "",
+ "};"
+ ],
+ "tail":[
"(function() {return JSON.stringify(motorBike);})();"
],
+ "solutions":[
+ "var car = {\n \"wheels\":4,\n \"engines\":1,\n \"seats\":5\n};\n\nvar motorBike = {\n \"wheels\": 4,\n \"engines\": 1,\n \"seats\": 2\n};"
+ ],
"challengeType":1,
- "type": "waypoint",
"type": "waypoint"
},
{
@@ -52,19 +55,23 @@
"title": "Construct JavaScript Objects with Functions",
"description":[
"We are also able to create objects using constructor
functions.",
- "Here's an example of a constructor function:",
+ "A constructor
function is given a capitalized name to make it clear that it is a constructor
.",
+ "Here's an example of a constructor
function:",
"var Car = function() {
",
" this.wheels = 4;
",
" this.engines = 1;
",
" this.seats = 1;
",
"};
",
- "Give your myMotorBike
object a wheels
, engines
and seats
attribute and set them to numbers.",
- "You may be confused by the this
keyword here. Don't worry, we will get to that very soon."
+ "In a constructor
the this
variable refers to the new object being created by the constructor. So when we write,",
+ " this.wheels = 4;
",
+ "inside of the constructor
we are giving the new object it creates a property called wheels
with a value of 4
.",
+ "You can think of a constructor
as a description for the object it will create.",
+ "Have your MotorBike
constructor
describe an object with wheels
, engines
and seats
properties and set them to numbers."
],
"tests":[
- "assert(typeof((new MotorBike()).engines) === 'number', 'message: myMotorBike
should have a engines
attribute set to a number.');",
- "assert(typeof((new MotorBike()).wheels) === 'number', 'message: myMotorBike
should have a wheels
attribute set to a number.');",
- "assert(typeof((new MotorBike()).seats) === 'number', 'message: myMotorBike
should have a seats
attribute set to a number.');"
+ "assert(typeof (new MotorBike()).engines === 'number', 'message: myMotorBike
should have a engines
attribute set to a number.');",
+ "assert(typeof (new MotorBike()).wheels === 'number', 'message: myMotorBike
should have a wheels
attribute set to a number.');",
+ "assert(typeof (new MotorBike()).seats === 'number', 'message: myMotorBike
should have a seats
attribute set to a number.');"
],
"challengeSeed":[
"var Car = function() {",
@@ -81,13 +88,107 @@
"",
"",
"",
+ "};"
+ ],
+ "tail":[
+ "var myMotorBike = new MotorBike();",
+ "(function() {return JSON.stringify(myMotorBike);})();"
+ ],
+ "solutions":[
+ "var Car = function() {\n this.wheels = 4;\n this.engines = 1;\n this.seats = 1;\n};\n\nvar myCar = new Car();\n\nvar MotorBike = function() {\n this.engines = 1;\n this.seats = 1;\n this.wheels = 4;\n};\n\nvar myMotorBike = new MotorBike();"
+ ],
+ "challengeType":1,
+ "type": "waypoint"
+ },
+ {
+ "id":"cf1111c1c15feddfaeb4bdef",
+ "title":"Make Instances of Objects with a Constructor Function",
+ "description":[
+ "Now let's put that great constructor
function we made in the last lesson to use!",
+ "To use a constructor
function we call it with the new
keyword in front if it like:",
+ "var myCar = new Car();
",
+ "myCar
is now an instance
of the Car
constructor that looks like the object it described:",
+ "{
",
+ " wheels: 4,
",
+ " engines: 1,
",
+ " seats: 1
",
+ "}
",
+ "Note that it is important to use the new
keyword when calling a constructor. This is how javascript knows to create a new object and that all the references to this
inside the constructor should be referring to this new object.",
+ "Now, once the myCar
instance
is created it can be used like any other object and can have its properties accessed and modified the same way you would usually. For example:",
+ "var myCar.turboType = \"twin\";
",
+ "Our myCar
variable now has a property turboType
with a value of \"twin\"
.",
+ "In the editor, use the Car
constructor
to create a new instance
and assign it to myCar
.",
+ "Then give myCar
a nickname
property with a string value."
+ ],
+ "tests":[
+ "assert((new Car()).wheels === 4, 'message: The property wheels
should still be 4
in the object constructor
.');",
+ "assert(typeof (new Car()).nickname === 'undefined', 'message: There should not be a property nickname
in the object constructor
.');",
+ "assert(myCar.wheels === 4, 'message: The property wheels
of myCar
should equal 4
.');",
+ "assert(typeof myCar.nickname === 'string', 'message: The property nickname
of myCar
should be a string.');"
+ ],
+ "challengeSeed":[
+ "var Car = function() {",
+ " this.wheels = 4;",
+ " this.engines = 1;",
+ " this.seats = 1;",
"};",
"",
- "var myMotorBike = new MotorBike();",
+ "// Only change code below this line.",
"",
- "// Only change code above this line.",
+ "var myCar;"
+ ],
+ "tail":[
+ "(function() {return JSON.stringify(myCar);})();"
+ ],
+ "solutions":[
+ "var Car = function() {\n this.wheels = 4;\n this.engines = 1;\n this.seats = 1;\n};\n\nvar myCar = new Car();\n\nmyCar.nickname = \"Lucy\";"
+ ],
+ "challengeType":1,
+ "type": "waypoint"
+ },
+ {
+ "id":"563cfb55594311ffcb333c70",
+ "title":"Make Unique Objects by Passing Parameters to our Constructor",
+ "description":[
+ "The constructor
we have is great, but what if we don't always want to create the same object?",
+ "To solve this we can add parameters
to our constructor
. We do this like the following example:",
+ "var Car = function(wheels, seats, engines) {
",
+ " this.wheels = wheels;
",
+ " this.seats = seats;
",
+ " this.engines = engines;
",
+ "};
",
+ "Now we can pass in arguments
when we call our constructor
.",
+ "var myCar = new Car(6, 3, 1);
",
+ "This code will create an object that uses the arguments
we passed in and looks like:",
+ "{
",
+ " wheels: 6,
",
+ " seats: 3,
",
+ " engines: 1
",
+ "}
",
+ "Now give it a try yourself! Alter the Car
constructor
to use parameters
to assign values to the wheels
, seats
, and engines
properties.",
+ "Then call your new constructor
with three number arguments
and assign it to myCar
to see it in action."
+ ],
+ "tests":[
+ "assert((function(){var testCar = new Car(3,1,2); return testCar.wheels === 3 && testCar.seats === 1 && testCar.engines === 2;})(), 'message: Calling new Car(3,1,2)
should produce and object with a wheels
property of 3
, a seats
property of 1
, and an engines
property of 2
.');",
+ "assert(typeof myCar.wheels === 'number' && typeof myCar.seats === 'number' && typeof myCar.engines === 'number', 'message: myCar
should have number values for the wheels
, seats
, and engines
properties.');"
+ ],
+ "challengeSeed":[
+ "var Car = function() {",
+ " //Change this constructor",
+ " this.wheels = 4;",
+ " this.seats = 1;",
+ " this.engines = 1;",
+ "};",
"",
- "(function() {return JSON.stringify(myMotorBike);})();"
+ "//Try it out here",
+ "var myCar;",
+ "",
+ "// Only change code above this line",
+ "",
+ "(function() {return JSON.stringify(myCar);})();"
+ ],
+ "solutions":[
+ "var Car = function(wheels,seats,engines) {\n this.wheels = wheels;\n this.seats = seats;\n this.engines = engines;\n};\n\nvar myCar = new Car(4,1,1);"
],
"challengeType":1,
"type": "waypoint"
@@ -97,89 +198,56 @@
"title":"Make Object Properties Private",
"description":[
"Objects have their own attributes, called properties
, and their own functions, called methods
.",
- "In the previous challenge, we used the this
keyword to reference public properties
and public methods
of the current object.",
+ "In the previous challenges, we used the this
keyword to reference public properties
of the current object.",
"We can also create private properties
and private methods
, which aren't accessible from outside the object.",
- "To do this, just declare properties or functions within the constructor.",
- "Let's create an object with two functions. One attached as a property and one not.",
- "See if you can keep myBike.speed
and myBike.addUnit
private, while making myBike.getSpeed
publicly accessible."
+ "To do this, we create the variable inside the constructor
using the var
keyword we're familiar with, instead of creating it as a property
of this
.",
+ "This is useful for when we need to store information about an object but we want to control how it is used by outside code.",
+ "For example, what if we want to store the speed
our car is traveling at but we only want outside code to be able to modify it by accelerating or decelerating, so the speed changes in a controlled way?",
+ "In the editor you can see an example of a Car
constructor
that implements this pattern.",
+ "Now try it yourself! Modify the Bike
constructor
to have a private property
called gear
and two public methods
called getGear
and setGear
to get and set that value."
],
"tests":[
- "assert(typeof(myBike.getSpeed)!=='undefined' && typeof(myBike.getSpeed) === 'function', 'message: The method getSpeed of myBike should be accessible outside the object.');",
- "assert(typeof(myBike.speed) === 'undefined', 'message: myBike.speed
should be undefined.');",
- "assert(typeof(myBike.addUnit) === 'undefined', 'message: myBike.addUnit
should remain undefined.');"
+ "assert(typeof myBike.getGear !== 'undefined' && typeof(myBike.getGear) === 'function', 'message: The method getGear
of myBike
should be accessible outside the object.');",
+ "assert(typeof myBike.setGear !== 'undefined' && typeof(myBike.setGear) === 'function', 'message: The method setGear
of myBike
should be accessible outside the object.');",
+ "assert(typeof myBike.gear === 'undefined', 'message: myBike.gear
should remain undefined.');"
],
"challengeSeed":[
"var Car = function() {",
- " // this is a private variable",
- " var gear = 1;",
- " // this is a private function (also known as a private method)",
- " function addStyle(styleMe){",
- " return 'The Current Gear Is: ' + styleMe;",
- " }",
- " // this is a public method",
- " this.getGear = function() {",
- " return addStyle(this.gear);",
+ " // this is a private variable",
+ " var speed = 10;",
+ "",
+ " // these are public methods",
+ " this.accelerate = function(change) {",
+ " speed += change;",
" };",
"",
+ " this.decelerate = function() {",
+ " speed -= 5;",
+ " };",
+ "",
+ " this.getSpeed = function() {",
+ " return speed;",
+ " };",
"};",
"",
"var Bike = function() {",
"",
" // Only change code below this line.",
"",
- " this.speed = 100;",
"",
- " function addUnit(value) {",
- " return value + \"KM/H\";",
- " }",
- "",
- " getSpeed = function () {",
- " return addUnit(speed);",
- " };",
"",
+ " // Only change code above this line.",
"};",
"",
- "// Only change code above this line.",
- "",
"var myCar = new Car();",
"",
- "var myBike = new Bike();",
- "",
- "if(myBike.hasOwnProperty('getSpeed')){(function() {return JSON.stringify(myBike.getSpeed());})();}"
+ "var myBike = new Bike();"
],
- "challengeType":1,
- "type": "waypoint"
- },
- {
- "id":"cf1111c1c15feddfaeb4bdef",
- "title":"Make Instances of Objects with a Constructor Function",
- "description":[
- "Sometimes you'll want to be able to easily create many copies of an objects that all share the same methods.",
- "Objects have their own attributes, called properties
, and their own functions, called methods
.",
- "You can create instances
of an object using a constructor
.",
- "A constructor is a function that creates instances of an object that share the same methods and properties",
- "Each new instance
of this object inherits
all the properties
and methods
of your original object.",
- "Once an instance
has been created you can add properties
to that instance
individually.",
- "Add an engines
property with a number value to the myCar
instance."
+ "tail":[
+ "if(myBike.hasOwnProperty('getGear')){(function() {return JSON.stringify(myBike.getGear());})();}"
],
- "tests":[
- "assert((new Car()).wheels === 4, 'message: The property wheels
should still be 4 in the object constructor.');",
- "assert(typeof((new Car()).engines) === 'undefined', 'message: There should not be a property engines
in the object constructor.');",
- "assert(myCar.wheels === 4, 'message: The property wheels
of myCar should equal 4.');",
- "assert(typeof(myCar.engines) === 'number', 'message: The property engines
of myCar should be a number.');"
- ],
- "challengeSeed":[
- "var Car = function() {",
- " this.wheels = 4;",
- "};",
- "",
- "// Only change code below this line.",
- "var myCar = new Car();",
- "",
- "",
- "",
- "// Only change code above this line.",
- "(function() {return JSON.stringify(myCar);})();"
+ "solutions":[
+ "var Car = function() {\n var speed = 10;\n\n this.accelerate = function(change) {\n speed += change;\n };\n\n this.decelerate = function() {\n speed -= 5;\n };\n\n this.getSpeed = function() {\n return speed;\n };\n};\n\nvar Bike = function() {\n var gear = 1;\n \n this.getGear = function() {\n return gear;\n };\n \n this.setGear = function(newGear) {\n gear = newGear;\n };\n};\n\nvar myCar = new Car();\n\nvar myBike = new Bike();"
],
"challengeType":1,
"type": "waypoint"
@@ -207,11 +275,8 @@
"",
"// Only change code below this line.",
"",
- "",
"var newArray = oldArray;",
"",
- "",
- "",
"// Only change code above this line.",
"",
"(function() {return newArray;})();"
@@ -239,13 +304,10 @@
"challengeSeed":[
"var array = [4,5,6,7,8];",
"",
- "",
"// Only change code below this line.",
"",
"var singleVal = array;",
"",
- "",
- "",
"// Only change code above this line.",
"",
"(function() {return singleVal;})();"
@@ -325,10 +387,10 @@
"description": [
"You can use the reverse
method to reverse the elements of an array.",
"reverse
is another array method that alters the array in place, but it also returns the reversed array.",
- "Add a line of code that uses reverse
to reverse the array
variable."
+ "Use reverse
to reverse the array
variable and assign it to myArray
."
],
"tests": [
- "assert.deepEqual(array, [7,6,5,4,3,2,1], 'message: You should reverse the array.');",
+ "assert.deepEqual(newArray, [7,6,5,4,3,2,1], 'message: You should reverse the array.');",
"assert(editor.getValue().match(/\\.reverse\\s*\\(\\)/gi), 'message: You should use the reverse
method.');",
"assert(editor.getValue().match(/\\[1\\,2\\,3\\,4\\,5\\,6\\,7/gi), 'message: You should only be using reverse
to modify array
.');"
],
@@ -337,11 +399,11 @@
"",
"// Only change code below this line.",
"",
- "",
+ "var newArray = array;",
"",
"// Only change code above this line.",
"",
- "(function() {return array;})();"
+ "(function() {return newArray;})();"
],
"challengeType": 1,
"type": "waypoint"