Skip to content

Commit

Permalink
Add basic inheritance and function.call exercises.
Browse files Browse the repository at this point in the history
  • Loading branch information
timoxley committed Oct 3, 2013
1 parent f95ba03 commit 73c2ec0
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 1 deletion.
4 changes: 3 additions & 1 deletion menu.json
Expand Up @@ -6,9 +6,11 @@
"Basic: Every Some",
"Basic: Reduce",
"Basic: Call",
"Basic: Inheritance",
"Implement Map with Reduce",
"Partial Application without Bind",
"Partial Application with Bind",
"Function Spies",
"Async Loops"
"Async Loops",
"Function Call"
]
43 changes: 43 additions & 0 deletions problems/basic_inheritance/problem.txt
@@ -0,0 +1,43 @@
##########
## Task ##
##########

Create an "BetterUser" that extends "User" by simply overriding
the User's toString method.

You will be passed a "User" constructor that looks like this:

```js

function User(name, age) {
this.name = name
this.age = age
console.info('NEW USER: ' + this)
}

```

#####################
## Expected Output ##
#####################

An `BetterUser` constructor function that extends User with a custom `toString` method that works like so:

var joe = new BetterUser('joe', 20) // pass in name and age
console.log('Hello ' + joe) // 'Hello [BetterUser joe (20)]'

#################
## Boilerplate ##
#################

```js
module.exports = function(User) {
// YOUR SOLUTION HERE
}
```

################
## Conditions ##
################

* Don't call the User constructor unnecessarily!
23 changes: 23 additions & 0 deletions problems/basic_inheritance/setup.js
@@ -0,0 +1,23 @@
var input = require('../../input')

module.exports = input()
.wrap(function(words, extend) {

function User(name, age) {
this.name = name
this.age = age
console.info('NEW USER: ' + this)
}

var BetterUser = extend(User)

console.log('creating new BetterUsers:')

console.log("new BetterUser('alice', 21)")
var alice = new BetterUser('alice', 21)
console.log('')

console.log("new BetterUser('joe', 20)")
var joe = new BetterUser('joe', 20)
console.log('')
})
13 changes: 13 additions & 0 deletions problems/basic_inheritance/solution.js
@@ -0,0 +1,13 @@
module.exports = function(User) {
function BetterUser() {
User.apply(this, arguments)
}

BetterUser.prototype = Object.create(User.prototype, {constructor: BetterUser})

BetterUser.prototype.toString = function() {
return '[BetterUser: '+this.name+' ('+ this.age +')]'
}

return BetterUser
}
88 changes: 88 additions & 0 deletions problems/function_call/problem.txt
@@ -0,0 +1,88 @@
##########
## Task ##
##########

Write a function that allows you to use `Array.prototype.slice` without
using `.call` to invoke it.

Normally you have to use slice with call or apply:

```js

var slice = Array.prototype.slice

function() {
var args = slice.call(arguments) // this works
}

```

We want this to work:

```js
var slice = yourFunction

function() {
var args = slice(arguments) // this works
}

```

#####################
## Expected Output ##
#####################

A function, `slice` that exhibits the following behaviour:

```js

var nums = [1,2,3,4,5]

// your slice function should match the regular
// behaviour of slice, except it takes the array
// as the first arguments

slice(nums, 0, 2) // [1, 2, 3]
slice(nums, 1, 2) // [2, 3]

// regular slice usage for comparison
nums.slice(0, 2) // [1, 2, 3]
nums.slice(1, 2) // [2, 3]
```

################
## Conditions ##
################

* Do not use the `function` keyword :D

#################
## Boilerplate ##
#################

```js

module.exports = // your solution here!

```

###########
## Hints ##
###########

* This is absolutely a one liner.
* Every JavaScript Function inherits methods such as call, apply and bind
from the object `Function.prototype`.
* Function#call executes whatever the value of `this` when it's invoked.
e.g. someFunction.call() // `this` inside `call` is `someFunction`
* Function.call itself is a function thus it inherits from `Function.prototype`

```js

var myFunction() {
console.log('called my function')
}

Function.prototype.call.call(myFunction) // => "called my function"

```
35 changes: 35 additions & 0 deletions problems/function_call/setup.js
@@ -0,0 +1,35 @@
"use strict"

var input = require('../../input')
var lorem = require('lorem-ipsum')

function randomInt(min, max) {
return Math.floor((Math.random() * max - min) + min)
}

function listOfWords() {
return lorem({count: 5, units:'words'})
.replace(/([^\w ])/g, '')// remove non-words and spaces
.toLowerCase() // lowercase I guess
.split(' ') // create array of words
}

var words = listOfWords()
module.exports = input(listOfWords())
.wrap(function(words, slice) {
words.forEach(function(words) {
console.log('words:', words)
console.log('')
console.log('slice(words):')
console.log(slice(words))
console.log('')
console.log('slice(words, 0, 1):')
console.log(slice(words, 0, 1))
console.log('')
console.log('slice(words, 2):')
console.log(slice(words, 2))
console.log('')
console.log('slice(words, -1):')
console.log(slice(words, -1))
})
})
13 changes: 13 additions & 0 deletions problems/function_call/solution.js
@@ -0,0 +1,13 @@
// Explained:
// The value of `this` in Function.call is the function
// that will be executed.
//
// Bind returns a new function with the value of `this` fixed
// to whatever was passed as its first argument.
//
// Every function 'inherits' from Function.prototype,
// thus every function, including call, apply and bind
// have the methods call apply and bind.
//
// Function.prototype.call === Function.call
module.exports = Function.call.bind(Array.prototype.slice)

0 comments on commit 73c2ec0

Please sign in to comment.