1

I apologize in advance if this question is very simple, I'm a beginner in JavaScript.

I found a wealth of information about a resembling pattern (module pattern) but unless I am mistaken, this is either something different or an extension. Here is a typical code excerpt from the (wonderful) domjs project by Mariusz Nowak:

renameReserved = (function (rename) {
    return function (scope) {
        Object.keys(scope).forEach(rename, scope);
    };
}(function (key) {
    if (contains.call(reserved, key)) {
        this['_' + key] = this[key];
        delete this[key];
    }
}));

I am finding it difficult to understand exactly what's happening here, even though each part taken independently is quite simple. Detailed help would be greatly appreciated, or a link to where I could learn more about this.

4
  • Note: I am currently reading about design patterns in JavaScript (addyosmani.com/resources/essentialjsdesignpatterns/book) but haven't gone through all of it yet, maybe my answer is there in which case I'm sorry. Commented Jul 26, 2014 at 14:58
  • I'm not sure what part's confusing you, so I'd suggest just sitting down and going through the evaluation of that expression step by step. If you get to a point where you don't know what happens next, then adding that to the question would clear things up. Commented Jul 26, 2014 at 15:00
  • Also without knowing what "contains" and "reserved" are, it's hard to explain why that code is written the way it is. Commented Jul 26, 2014 at 15:00
  • @Pointy Thanks a lot for your comments; what I find difficult to understand is what will happen upon a call of renameReserved? The variables contains and reserved come from EcmaScript5 (from a required instruction at the beginning of the program). Commented Jul 26, 2014 at 15:04

2 Answers 2

3

There are two functions involved here. First one

function (rename) {
    return function (scope) {
        Object.keys(scope).forEach(rename, scope);
    };
}

And the other function object is passed as an argument to this function

function (key) {
    if (contains.call(reserved, key)) {
        this['_' + key] = this[key];
        delete this[key];
    }
}

Since we execute the first function, with an argument, (rename is the parameter which holds the function object passed) it returns another function which holds the function which we passed as argument because of the closure property.

Sign up to request clarification or add additional context in comments.

1 Comment

So then renameReserved will be the function returned by the first anonymous function (of rename), in which the first parameter of forEach is the second anonymous function (of key)?
1

I'm going to rewrite the code in a way that won't change what happens, but may make it a little clearer:

function makeNameReplacer( rename ) {
    return function( scope ) {
        Object.keys(scope).forEach(rename, scope);
    }
}

function reservedWordRenamer( key ) {
    if (contains.call(reserved, key)) {
        this['_' + key] = this[key];
        delete this[key];
    }
}

renameReserved = makeNameReplacer( reservedWordRenamer );

So the first function is something that creates a function. The created function applies a name-substitution strategy to all the property names in a given object ("scope").

The second function is a strategy for replacing property names. Specifically, it checks to see if the property name passed in ("key") is in the set of reserved words. If it is, it replaces it with the name prefixed by an underscore, and removes the old property.

Thus the overall effect is that "renameReserved" becomes a function, one that takes an object as a parameter and which will scrub out property names that are reserved words.

You could come up with another strategy, and make another function. For example, if you wanted objects whose property names were all upper-case, you could do this:

function upperCaseRenamer( key ) {
  var uckey = key.toUpperCase();
  if (key !== uckey) {
      this[uckey] = this[key];
      delete this[key];
  }
}

renameLowerCase = makeNameReplacer( upperCaseRenamer );

1 Comment

Thanks a lot, this is perfectly clear; I would call this pattern a "functional" (a function of functions, which is actually exactly what it reads..). I'm really amazed by the simplicity with which such sophisticated concepts can be rendered in JavaScript! Thanks again for your explanation.

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.