2

I would like a function 'get' that takes an id, an optional property parameter and a callback function. It would be used like so:

get(14297, 'name', function processName(name) {...});
get(14297, function processStudent(student) {...});

I have included one possible implementation below

function get(id, property, callback) {
    var item = ...;
    // property is callback
    if (!callback) property(item);
    // callback is callback
    else callback(item[property])
}

It feels a little bit weird because

property(item);

Is actually a callback function depending on the context. Is there a better way to do this?

1
  • Which parameters are "required", only id, or callback as well? Commented May 15, 2012 at 8:39

4 Answers 4

4

You should switch the parameters. Try this

function get(id, callback, property)
{
    if(typeof property === "undefined")
        callback(item);
    else
        callback(item[property]);
}
Sign up to request clarification or add additional context in comments.

4 Comments

there are plenty of examples in the jQuery source where the middle parameters are optional - it doesn't have to be the last ones.
indeed not, just pointing out that it is not uncommon to have optional middle parameters
If you need a framework to handle that, it might be uncommon in native JavaScript!
sigh - I'm not suggest that you need a framework for it! The jQuery API just happens to use this feature.
2

You can change the order of parameters, or test what the function is given to work out what they are. e.g.

function get(id, property, callback) {
  if (arguments.length == 2) {
    // second argument is callback
    callback = property;
    property = void 0;
  }
  ...
}

or

function get(id, property, callback) {
  if (typeof property == 'function') {
    // second argument is callback
    callback = property;
    property = void 0;
  }
  ...
}

and so on, but that type of overloading is not particularly liked.

Comments

2

This is the pattern used by jQuery:

function get(id, property, callback) {

    // if the 2nd parameter is a function, assume that
    // only two parameters were supplied
    if (typeof property === 'function') {
         callback = property;
         property = undefined;
    }

    ...
}

Effectively, if it sees unexpected parameter types it just shuffles their contents around until they match the alternative definition.

6 Comments

The arguments object isn't a pseudo–array, it's just an arguments object.
@RobG I've changed my answer, but AFAIK arguments is a pseudo-array. Is has .length and [n] properties, and subsequently can be coerced into a real array using [].prototype.slice().
That does not handle empty middle parameter naturally. You have to know what to expect as value of the parameter. Maybe jQuery has to deal with this stuff so that the user can use their methods as they like. But if the OP is implementing the method himself, he should not implement it that way!
@Alnitak—pseudo actually means "false" or "pretend", something masquerading as something it isn't. The arguments object does have a length parameter, and it's members can be accessed by index, but that's where the similarity ends. Array.prototype methods are mostly (all?) specified as generic so as to work on any suitable native (and often host) object. It might be called a quasi–array, but maybe I'm being pedantic. ;-)
@RobG if it walks like a duck, and quacks like a duck, it's a pseudo-duck ;-) Unsure about your last sentence - by definition functions on Array.prototype cannot work directly on arguments since its prototype is wrong. Can you expand, or give an example?
|
0

The arguments object is immutable. But you can slice it in an array, pop the last argument and deal with the other arguments as you normally would, since you know the callback argument isn't in it anymore.

Here is a way to do this:

function get() {
    // Copy the `arguments` object in an array, since it's immutable
    var args = Array.prototype.slice.call( arguments, 1 ),

    // Pop the last argument of the arguments
        callback = args.pop();

    // Then deal with other arguments
    // For example, check for the existence of the second argument
    if ( args[1] ) {
    }

    // Then, you can call the callback function
    callback();
}

Comments

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.