2

I came across a coding "test" that asked for code that would do the following:

Using JavaScript, implement a 'chart' function according to the example:

Note: '===' is used below to communicate the expected output.

var myBarChart = chart();
myBarChart.type() === 'line';
myBarChart.type('bar');
myBarChart.type() === 'bar';
myBarChart() === "Here's your bar chart!"; // THIS IS WHAT I CAN'T DO

var myScatterChart = chart().type('scatter');
myScatterChart() === "Here's your scatter chart!"; // THIS EITHER

It was relatively simple to implement the chart() object and the type() method. I got all the expected results. What I could not come up with, however, was a way to get myBarChart() and myScatterChart() to return a string.

I could override the object's toString() method so that something like the following would work:

console.log(myBarChart + ''); // 'bar'

But not get anything that would work in this form:

console.log(myBarChart()); // Looking for 'bar', but never got there

Basically, I could never get get whatever() to return a string while whatever.type() was a valid method.

Is there a way to do this that is just unknown to me?

1
  • 1
    Hint: you can't make objects behave like functions but you can make functions behave like objects Commented Mar 11, 2015 at 3:58

2 Answers 2

2

Let us first understand the requirements.

  1. You need to create a Chart function which can return a function which has a property type which can either be used as a setter or getter.

  2. The type function, when called with no arguments, should return the actual type.

  3. And the default type should be line.

  4. The type function when called with one argument, it should set the actual type of chart and it should return a function in such a way that, you can again invoke it to get the Here's your chart.. message.

All right. Now, lets see how we can write this in code.

function Chart() {
    // Default type. Req 3
    var type = 'line';

    // Core function
    var func = function() {
        return "Here's your " + type + " chart!";
    };

    // Req 1
    func.type = function(value) {
        // Req 2
        if (arguments.length === 0) {
            return type;
        }
        // Req 4
        type = value;
        return func;
    }
    // Req 1
    return func;
}

Test cases:

var myBarChart = Chart();
console.assert(myBarChart.type() === 'line');
myBarChart.type('bar');
console.assert(myBarChart.type() === 'bar');
console.assert(myBarChart() === "Here's your bar chart!");

var myScatterChart = Chart().type('scatter');
console.assert(myScatterChart() === "Here's your scatter chart!");
Sign up to request clarification or add additional context in comments.

1 Comment

Excellently crafted answer. Thanks very much.
1

To create a function that also acts as an object, you can do something like this:

var Example = function(params){
  this.params = params;
}

Example.prototype.prompt = function(){
  console.log(this.params);
}

var test = new Example("Hello, how are you?");
test.prompt();

Now, if you're asking how to create something where you have a function that initiates a new ovject each time it's called, you can impliment something like this:

var Example = function(params){
  this.params = params;
}

Example.prototype.prompt = function(){
  console.log(this.params);
  return this;
}

Example.prototype.change = function(data){
  this.params = data;
  return this;
}

myInit = function(data){
  return new Example(data);
}

myInit("Hello!").prompt().change("How are you?").prompt();

In your case, you want to create a variable for the initate function, so you'd do something like this:

var test = myInit("Default param.");
test.prompt();
test.change("Hello!");
test.prompt();

(JS Fiddle Example)

4 Comments

Your answer is better than mine, which was going to be: Google "JavaScript Object Prototypes".
Lol, I do agree, Google is our friend. But I don't think posting that as an answer would cut it on StackOverflow. :)
I actually spent a fair bit of time on Google before posting. I also spent an hour trying to code the solution myself, having looked at many of the pages that come up when searching on "Javascript Object prototypes". The thing is, you don't actually need to use prototypes to accomplish what the test asked for. What I was missing was that you can simply add a method to a function that is being returned as the return value for another function. Your answer doesn't demonstrate that - I knew everything in your answer already, though I appreciate your effort in trying to help.
@MichaelOryl Ohh, I apologize, I thought you just needed a general overview. I'll leave this answer up anyways for future visitors.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.