-
-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Object Oriented Programming Challenges #15
Comments
I'm willing to take this on as the project owner. |
@utsab awesome! Yes - we need to expand this. First things first, could you create a list of challenge titles? OOP is probably complicated enough that we could have 20 or 30 challenges associated with it. |
@utsab I've promoted you to topic owner. |
@QuincyLarson yes, I'll compile a list of challenge titles. I'll try to have this done by Wednesday. |
Here's a 1st draft of the topics for OOJS. (The pre-existing challenges are marked with hash tag #old):
Constructors
More on "this"
Prototypes
Prototypes with Constructors
Inheritance
Encapsulation (Data hiding)
Other
Looking forward to hearing your feedback @QuincyLarson and anyone else who would like to discuss. |
@alayek, great! Glad to have your help on this. I messaged you on gitter about setting up a time to chat. |
@utsab Thanks for your patience with my slow response. This is an excellent list of OOP concepts! I am so excited about this. We will finally give OOP the level of detail it deserves. Let me know if I can be of any help with designing these challenges, their descriptions, and tests. I will look forward to seeing them here as you have time to add them :) |
@utsab Thanks for the call. |
@utsab great talking with you! I will take on Mixins and Encapsulation (Data hiding). |
@utsab Great talk, thanks for onboarding me. As discussed, I will be covering Inheritance. |
@utsab Thanks for chatting, glad to be contributing! I am going to cover Constructors. |
@utsab Great to be helping! We made a bit of a change to the curriculum and created an Objects section, which I'll be working on. |
Hey Quincy! I'll be posting my challenges now. We went ahead and made a basic Objects section that we'll need to update the original curriculum list to include. Challenge Name: Introduction to Objects Challenge Create a basic JavaScript object. Challenge Description Think about things we encounter in our everyday life, like cars, shops, and birds. These are all objects: tangible things we can observe and interact with. What are some qualities of these We can use var duck = {
name: "Aflac",
numLegs: 2
} We created a “duck” object with two property/value pairs: a Instructions Create a “dog” Challenge Seed var dog = {
//Your code here
} Challenge Tests Test to verify that the dog object is defined. Test to verify that the dog object has name and numLegs properties. Challenge Solution var dog = {
name: //string,
numLegs: //number
} |
Challenge Name: Accessing Properties on Objects Challenge Use dot notation to access object’s properties. Challenge Description Great job on defining that “dog” It's very simple to access the values of a property on an var duck = {
name: "Aflac",
numLegs: 2
}
console.log(duck.name)
//This will print "Aflac" to the console. By using our Instructions Print the properties of the Dog object below to your console. Challenge Seed var dog = {
name: “Spot”,
numLegs: 4
}
//Add your two console calls here. Challenge Tests Test to see that the Dog’s name prints to the console. Test to see that the Dog’s numLegs prints to the console. Challenge Solution var dog = {
name: “Spot”,
numLegs: 4
}
console.log(dog.name);
console.log(dog.numLegs); |
Challenge Name: JavaScript Object Methods Challenge Create a method on an object. Challenge description Now that we know how to create an
var duck = {
name: "Aflac",
numLegs: 2
sayName: function() {return "The name of this duck is " + duck.name + "."}
}
duck.sayName();
//This will return "The name of this duck is Aflac." As you can see above, we added the Notice that we access the Instructions In the following exercise, draw upon the previous “dog” Challenge Seed var dog = {
name: “Spot”,
numLegs: 4
//Add your method here.
}
dog.sayLegs(); Challenge Tests Test to see if the Dog Challenge Solution var dog = {
name: “Spot”,
numLegs: 4
sayLegs: function() {return "This dog has " + dog.legs + " legs."}
}
dog.sayLegs(); |
Challenge Name: Introducing "This" Challenge Make code more reusable with “this”. Challenge Description We are going to look at our sayName: function() {return "The name of this duck is " + duck.name + "."} Notice how we are referencing the variable name of our object, What if the variable name of our There's a way to avoid that all. Introducing... var duck = {
name: "Aflac",
numLegs: 2,
sayName: function() {return "The name of this duck is " + this.name + "."}
}
Now, if we changed our object's name to mallard, we don't have to find all our references to Instructions Modify the Challenge Seed var duck = {
name: "Aflac",
numLegs: 2,
sayName: function() {return "The name of this duck is " + this.name + "."}
};
// Modify code below this line.
var dog = {
name: “Spot”,
numLegs: 4,
sayLegs: function() {return "This dog has " + dog.numLegs + " legs."}
};
dog.sayLegs(); Challenge Tests Test to see if Challenge Solution var dog = {
name: “Spot”,
numLegs: 4,
sayLegs: function() {return "This dog has " + this.numLegs + " legs."}
}
dog.sayLegs(); |
Challenge - 1Use a What is a MixinAs you have previously seen you can share behaviour through For unrelated objects, it's better to use var flyMixin = function(obj) {
obj.fly = function() {
console.log("Flying, wooosh!")
}
} The var bird = {
name: “Donald”,
numLegs: 2,
}
var plane = {
model: “777”,
numPassengers: 524
}
flyMixin(bird);
flyMixin(plane); Here bird.fly(); //results in output on the screen: Flying, wooosh!
plane.fly(); //results in output on the screen: Flying, wooosh! Note how the InstructionsCreate a Challenge Seedvar bird = {
name: ‘Donald’,
numLegs: 2,
}
var boat = {
name: 'Warrior',
type: 'race-boat',
}
// Only add code below this line. Challenge Testsassert(/var glideMixin = function(.+)/.test(code), ‘message: Please use the `var glideMixin` and set it equal to an anonymous function’
assert(typeof glideMixin === "function", ‘message: `glideMixin` should follow the proper structure of a function)
assert(/glideMixin\(.+\)/.test(code), ‘message: Don’t forget to pass the object to your mixin, to give it access to `.glide` method’ Challenge Solutionvar glideMixin = function(obj) {
obj.glide = function() {
console.log("Gliding on the water")
}
}
glideMixin(bird);
glideMixin(boat); |
Challenge - 2Use closure to protect Introduction to Private PropertiesIn the previous challenge, bird.name = "Duffy" Any part of your code can therefore easily change the name of The simplest way to make properties function Bird() {
var hatchedEgg = 10; // private property
this.getHatchedEggCount = function() { //publicly available method that a bird object can use
return hatchedEgg();
}
}
ducky = new Bird();
ducky.getHatchedEggCount() //returns 10 Here InstructionsChange the Challenge Seed// rewrite the function below
function Bird() {
this.weight = 15;
} Challenge Testsassert(/var weight/.test(code), 'message: Please use the `var` before the weight to make it private'
assert(/function handleWeight\(\) {/.test(code), 'message: Please make sure to create a named function within your Bird object'
assert(/return weight;/.test(code), 'message: Please remember to have a return statement for your private weight variable'
assert(/this.getWeight = function\(\) {/.test(code), 'message: Make sure to have a public method that an instance of your `Bird` can call on' Challenge Solutionfunction Bird() {
var weight = 15;
function handleWeight() {
return weight;
}
this.getWeight = function() {
return handleWeight();
}
} Resourceshttps://curiosity-driven.org/private-properties-in-javascript |
Challenge - 3Understand the immediately invoked function Expression (IIFE) Challenge DescriptionA common pattern in javascript is to execute a function as soon as it is declared: (function () {
console.log("Chirp, chirp!")
})(); // this is the anonymous function expression that executes right away
// Outputs "Chirp, chirp" immediately Note that the function has no name and is not stored in a variable. The two parentheses InstructionsRewrite the function in the text editor to be an immediately invoked function expression (IIFE). Challenge Seedfunction makeNest() {
console.log("A cozy nest is ready");
}
makeNest(); Challenge Testsassert(/\(function\(\) {/.test(code), 'message: Make sure your new function is anonymous'
assert(/}\)\(\)/.test(code), 'message: Don’t forget to have double parentheses at the end of your function expression' ##Challenge Solution (function() {
console.log("A cozy nest is ready")
})(); |
Challenge - 4Use an IIFE to create a module Challenge DescriptionAn immediately invoked function expression (IIFE) is often used to group related functionality into a single object or function glideMixin(obj) {
obj.glide = function() {
console.log("Gliding on the water")
}
}
function flyMixin(obj) {
obj.fly = function() {
console.log("Flying, wooosh!")
}
} We can group these mixins into a var motionModule = (function () {
return {
glideMixin: function (obj) {
obj.glide = function() {
console.log("Gliding on the water")
}
},
flyMixin: function(obj) {
obj.fly = function() {
console.log("Flying, wooosh!")
}
}
}
}) (); // The two parentheses cause the function to be immediately invoked Note that we have an immediately invoked function expression (IIFE) whose sole purpose is to return an object. The advantage of the motionModule.glideMixin(duck);
duck.glide(); InstructionsCreate a Challenge Seedvar isCuteMxin = function(obj) {
obj.isCute = function() {
return true
}
}
var singMixin = function(obj) {
obj.sing = function() {
console.log("Singing to an awesome tune");
}
} Challenge Testsassert(typeof funModule !== undefined, "message: <code>funModule</code> should be defined");
assert(funModule.isCuteMixin !== undefined, "message: <code>funModule.isCuteMixin</code> should be defined");
assert(funModule.singMixin !== undefined, "message: <code>funModule.singMixin</code> should be defined"); Challenge Solutionvar funModule = (function () {
return {
isCuteMixin: function (obj) {
obj.isCute = function() {
return true
}
},
singMixin: function(obj) {
obj.sing = function() {
console.log("Singing to an awesome tune")
}
}
}
}) (); |
@venture-vin @silvestrijonathan great work! Could you please point which of the items in the roadmap these challenges point to? I will update the roadmap |
@alayek - no problem did you want that in the beginning of each comment, and did you want general topics or the more specific topics? (Mine are Mixin & Data Encapsulation) |
If you are adding challenges that are not mentioned in the roadmap, that's still fine. Just copy the roadmap and check off the item you are taking. Or copy it, add the item where it would fit in, and check it off. I have updated one of the challenges you have submitted.You wanted some help with how to introduce Closures without going into concepts of garbage collector etc. We can discuss if you are available. |
@alayek, I'll go back and add those in after we discuss how we'll be adding them to the roadmap. Thanks! |
InheritanceChallenge 3: Set the Child's Prototype to an Instance of the ParentUpdated: 08/24/16 Challenge Challenge: Set the Child's Prototype to an Instance of the Parent Challenge Description In this challenge, we cover the next step: set the prototype of the Bird.prototype = Object.create(Animal.prototype); What does that do for us? Remember that the prototype is like the "recipe" for creating an object. In a way, we are saying that the recipe for var duck = new Bird("Donald");
duck.eat(); // prints "nom nom nom"
Instructions Modify the code so that instances of Challenge Seed function Animal() {
};
Animal.prototype = {
constructor: Animal,
eat: function() {
console.log("nom nom nom");
}
}
function Dog() {
};
//
// Add code here
//
var beagle = new Dog();
beagle.eat(); //Should print "nom nom nom" Challenge Tests Challenge Solution function Animal() {};
function Dog() {};
Animal.prototype.eat = function () { console.log("nom nom nom"); };
Bird.prototype = Object.create(Animal.prototype);
var beagle = new Dog();
beagle.eat(); // prints "nom nom nom" |
InheritanceChallenge 2: Inherit Behaviors From A SupertypeUpdated: 08/22/16 Challenge Challenge Description In the previous challenge, we created a function Animal() { };
Animal.prototype.eat = function() {
console.log("nom nom nom");
} In this and the next challenges, we will learn how to reuse This challenge will cover the first step: make an We already know one way to create an instance of var animal = new Animal(); There are some disadvantages when using this syntax for inheritance, which are too complex for the scope of this challenge. Instead, we show a better approach: var animal = Object.create(Animal.prototype);
animal.eat(); // prints "nom nom nom"
animal instanceof Animal; //=> true Instructions Use Challenge Seed function Animal(){
}
Animal.prototype = {
constructor: Animal,
eat: function() {
console.log("nom nom nom");
}
}
// Modify the code below this line
var duck =
var beagle =
duck.eat(); // Should print "nom nom nom"
beagle.eat(); //Should print "nom nom nom" Challenge Tests assert(duck instanceof Animal, 'message: Did you remember to assign the Animal prototype to duck?') Challenge Solution function Animal(){
}
Animal.prototype = {
constructor: Animal,
eat: function() {
console.log("nom nom nom");
}
}
// Modify the code below this line
var duck = Object.create(Animal.prototype);
var beagle = Object.create(Animal.prototype);
duck.eat(); // Should print "nom nom nom"
beagle.eat(); //Should print "nom nom nom" |
InheritanceChallenge 5: Add Own Methods To Inherited PrototypeUpdated: 08/22/16 Challenge Challenge Description Let's use function Animal() {}
Animal.prototype.eat = function () { console.log("Nom nom nom"); };
function Bird() {}
Bird.prototype = Object.create(Animal.prototype);
Bird.prototype.constructor = Bird; In addition to what is inherited from Animal, we want to add behavior that is unique to birds. Let’s give Now instances of var duck = new Bird;
duck.eat(); // prints "Nom nom nom"
duck.fly(); // prints "I'm flying!" Instructions Hint Challenge Seed function Animal(){};
Animal.prototype.eat = function () { console.log("Nom nom nom"); };
function Dog() {};
// Add code below this line
// Add code above this line
var beagle = new Dog;
beagle.eat(); // prints "Nom nom nom"
beagle.bark(); // prints "Woof!"
**Challenge Tests**
assert(typeof Animal.prototype.bark == "undefined", 'message: Only instances of Dog should respond to the .bark() method');
assert(!(typeof Dog.prototype.eat == "undefined"), 'message: Dog should inherit the .eat() method from Animal');
assert(beagle instanceof Animal, 'message: Dog should inherit the .eat() method from Animal');
assert(beagle.constructor === Dog, 'message: Did you remember to the constructor for Dog?');
**Challenge Solution**
```javascript
function Animal(){};
Animal.prototype.eat = function () { console.log("Nom nom nom"); };
function Dog() {};
// Add code below this line
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function () {};
// Add code above this line
var beagle = new Dog;
beagle.eat(); // prints "Nom nom nom"
beagle.bark(); |
InheritanceChallenge 6: Override Inherited MethodsUpdated: 08/24/16 Challenge Challenge Description We can override an inherited method the same way by adding a method to Here's an example of Bird overriding the function Animal(){}
Animal.prototype.eat = function() { return "Nom nom nom"; };
function Bird(){}
// inherit methods first, followed by method overrides
Bird.prototype = Object.create(Animal.prototype);
// Bird.eat() overrides Animal.eat()
Bird.prototype.eat = function () { return "Peck peck peck"; }; If we have an instance
Instructions Override the Challenge Seed function Bird(){}
Bird.prototype.fly = function () { return "I'm flying!"; };
function Penguin(){}
Penguin.prototype = Object.create(Bird.prototype);
Penguin.prototype.constructor = Penguin;
// Only add code below this line
// Only add code above this line
var penguin = new Penguin;
console.log(penguin.fly()); Challenge Tests assert((new Bird).fly() === "I'm flying!", 'message: assert(penguin.constructor === Penguin, 'message: Did you remember to the constructor for Penguin?'); Challenge Solution function Bird(){}
Bird.prototype.fly = function () { return "I'm flying!"; };
function Penguin(){}
Penguin.prototype = Object.create(Bird.prototype);
Penguin.prototype.constructor = Penguin;
// Only add code below this line
Penguin.prototype.fly = function () {
return "Alas, this is a flightless bird.";
}
// Only add code above this line
var penguin = new Penguin;
console.log(penguin.fly()); |
InheritanceChallenge 4: Reset An Inherited Constructor PropertyUpdated 08/24/16 Challenge Challenge Description Example: function Bird(){};
Bird.prototype = Object.create(Animal.prototype);
var duck = new Bird;
duck.constructor // function Animal(){...} Uh oh! We want Instructions Fix the code so Challenge Seed function Animal(){}
function Bird(){}
function Dog(){}
Bird.prototype = Object.create(Bird.prototype);
Dog.prototype = Object.create(Bird.prototype);
//
// Add code here
//
var duck = new Bird;
var beagle = new Dog; Challenge Tests assert(duck.constructor === Bird, 'message: duck.constructor should return Bird'); assert(Animal.prototype.isPrototypeOf(Dog.prototype), 'message: assert(beagle.constructor === Bird, 'message: Challenge Solution function Animal(){}
function Bird(){}
function Dog(){}
Bird.prototype = Object.create(Animal.prototype);
Dog.prototype = Object.create(Animal.prototype);
Bird.prototype.constructor = Bird;
Dog.prototype.constructor = Dog;
var duck = new Bird;
var beagle = new Dog; |
@user512 Excellent work, Tom! These are coming along great. You do an excellent job of explaining these concepts, and these challenges are really well conceived. |
Credit to @utsab. He is great at leading the team and teaching these concepts. |
Here is the final list of topics. Note that this is different than what is posted in the first comment. @alayek, can you please update the first comment with this new list? Thank you. Objects
Constructors
Prototypes
Inheritance
Other
The final version of all of these challenges is located in this google doc |
@utsab yeah I was just about to update the first comment. Thanks! |
@utsab Excellent! Could you check the boxes that correspond to your created challenges so we can see which challenges remain to be created? |
InheritanceChallenge 1: Don't Repeat YourselfChallenge Challenge Description Notice in the example below that the Bird.prototype = {
constructor: Bird,
describe: function() {
console.log("My name is " + this.name);
}
};
Dog.prototype = {
constructor: Dog,
describe: function() {
console.log("My name is " + this.name);
}
}; The function Animal(){
};
Animal.prototype = {
constructor: Animal,
describe: function() {
console.log("My name is " + this.name);
}
}; Since Bird.prototype = {
constructor: Bird
};
Dog.prototype = {
constructor: Dog
}; Instructions The Challenge Seed function Cat(name) {
this.name = name;
};
Cat.prototype = {
constructor: Cat,
eat: function() {
console.log("nom nom nom");
}
};
function Bear(name) {
this.name = name;
};
Bear.prototype = {
constructor: Bear,
eat: function() {
console.log("nom nom nom");
}
};
function Animal(){
};
Animal.prototype = {
constructor: Animal
}; Challenge Tests Test that Animal.prototype has the Challenge Solution function Cat(name) {
this.name = name;
};
Cat.prototype = {
constructor: Cat
};
function Bear(name) {
this.name = name;
};
Bear.prototype = {
constructor: Bear;
};
function Animal(){
};
Animal.prototype = {
constructor: Animal,
eat: function() {
console.log("nom nom nom");
}
}; |
@QuincyLarson, I updated the list of topics and checked off the completed challenges. Every challenge except one (calling a supertype method) was created. Since there were a few people creating challenges for this topic, I went through everyone's challenges and updated them for stylistic consistency. The final version of all of these challenges is located in this google doc. Is this an acceptable way to submit the final versions of the challenges? |
Hello @QuincyLarson @utsab and everyone else on this chain - I'm currently working on this section in the QA process and have a couple questions. Right now, these challenges are ordered to come after the ES6 section (see #46) and we've been converting the other new JS sections so their examples/seed code use ES6 syntax. (This is done for Regex and Debugging so far). Is this section replacing the current FCC Object Oriented section, or will it be layered with it? If it's replacing that section, should we convert this into ES6 syntax to be consistent? Given the new class syntax, does this materially change any of the challenges? If we are converting to ES6 - I'm relatively new to using it, and would appreciate help to make sure the conversion is done correctly. Let me know, thanks! (Side note @QuincyLarson - this comment would also apply to the Functional Programming and the Advanced Data Structures sections as well) |
@HKuz we plan to completely eliminate the old OOP/FP section. Another note on this: what we are teaching is not technically ES6 - it is ES2016, which is two generations ahead of ES6. Me and @BerkeleyTrue's thinking is we should just merge the ES6 section into the JavaScript section and call it "JavaScript". Then we can use the latest syntax in all of our challenges. I will do this once we finish the ES6 section. It shouldn't affect your QA process. |
@QuincyLarson okay, thanks for clarifying. Makes sense to combine all the JS challenges together. I'll keep plugging on the QA process. |
@HKuz great - it's a plan 🙂 We can assume that all JavaScript-related challenges on FCC can use ES2016 syntax, then. |
@HKuz and @QuincyLarson, the original outline for the OOJS challenges does not factor in the ES6 "class" syntax. If we do emphasize the "class" syntax, then maybe we do not need the prototype-chain sections. With the new "class" syntax, we no longer need to use the prototype chain to implement inheritance. |
@utsab my understanding is that the "class" syntax is just syntactic sugar. These objects still use prototypical inheritance. Perhaps @BerkeleyTrue or @alayek could chime in here. If this is the case, we could introduce the class keyword after we finish covering prototypes, and explain how it makes things more convenient. |
@utsab et al - if you all do decide to add a new challenge, you can post it here and mention me. I'm almost through reviewing the others and adding a new one is not a problem. Just let me know where it would go in the order 😄 Thanks! |
Hi folks - here's a first cut of the introductory text for this section. This is meant to be a standalone intro, but the following section is Functional Programming. That's why I included the language about different approaches to software development - I'm thinking it'll help transition between the sections and tie them together. Any comments or suggestions are welcome 😄 Introduction to the Object Oriented Programming ChallengesAt its core, software development solves a problem or achieves a result with computation. The software development process first defines a problem, then presents a solution. Object oriented programming is one of several major approaches to the software development process. As its name implies, object oriented programming organizes code into object definitions. These are sometimes called classes, and they group together data with related behavior. The data is an object's attributes, and the behavior (or functions) are methods. The object structure makes it flexible within a program. For example, objects can exchange information with each other. One object would invoke a method and send data to the other in a process called message passing. Object oriented programming uses the concept of inheritance. It allows a new class to inherit, or receive, all the features from a base or parent class plus a few of its own. Inheritance helps to avoid repeated code by reusing it between related classes. Your choice of programming approach depends on a few factors. The type of problem, and how you want to structure your data and algorithms make a difference. This section covers object oriented programming principles in JavaScript. |
@HKuz Excellent description. I would avoid using the word "invoke" here unless we've used it before this point. As with the other descriptions, I think this could ultimately be boiled down to just 2 or 3 paragraphs. It wouldn't be as comprehensive as this explanation is, but a lot more people would read the entire thing. |
@QuincyLarson thanks for the feedback and apologies for the delayed response, I was on the road and my internet was all wonky this weekend from that ddos attack. I can rework this and get it in the next iteration of the feature/curriculum-expansion branch. |
@HKuz No need to apologize - I'm happy your receptive to making this small change. I hope you had a fun weekend on the road. |
@QuincyLarson how is it going with the new curriculum? Is there anything I can do to help? |
@alookatommorow thanks for your offer. We are getting quite close to pushing this to beta. Look for an announcement in the coming weeks. In the meantime, you can help hanging out on our forum and helping us QA some of the new projects we're designing by building them yourself: https://forum.freecodecamp.com/c/meta |
Ok, great. Thanks @QuincyLarson |
@utsab is in charge of coordinating the expansion of these challenges, but he needs your help.
For each challenge, please reply to this GitHub issue with:
Here are the challenges we have currently planned (these can be further expanded):
Objects
Constructors
instanceof
Prototypes
Inheritance
Other
Mixin
to add common behavior between unrelatedobjects
properties
within anobject
from being modified externally.Here are the challenges as we originally discussed for archival purposes:
The text was updated successfully, but these errors were encountered: