1

I've been seeing the syntax:

var module = {

    func: function(value) {

        some code;

    }.func2("value");

}

cropping up in various places, as am wondering how this is done. I remember seeing an article about it a while back, but can't find it now. Whatever I try .func2("value") just trows syntax errors.

For example, take a look at SproutCore's intro to their TemplateView.

Todos.StatsView = SC.TemplateView.extend({
  remainingBinding: 'Todos.todoListController.remaining',

  displayRemaining: function() {
    var remaining = this.get('remaining');
    return remaining + (remaining === 1 ? " item" : " items");
  }.property('remaining').cacheable()
});

Seems like it would be a useful tool to give users when writing factories.

Thanks.

nicholas
  • 14,184
  • 22
  • 82
  • 138

3 Answers3

1

You can add properties to Function's prototype and then chain function definitions. For example:

Function.prototype.trigger = function(trigger) {

    var setValue = this;

    return function(thevalue) {
        alert(trigger + ' set to ' + thevalue);
        setValue(thevalue);
    };

};

var _value = 0;

var setValue = function(thevalue) {

    _value = thevalue;

}.trigger('value');

setValue(25);

When setValue is defined the trigger function is called within the scope of the anonymous function it's chained to, and setValue is assigned the value returned by trigger. In this case we're just alerting that setValue is being called, but this opens some very cool possibilities.

Pretty slick.

nicholas
  • 14,184
  • 22
  • 82
  • 138
0

The syntax I think you are looking for it is:

func: (function(value) {
    //some code;
}("value"));

In which the anonymous function is called immediately and its return value assigned to func.

See also: How do JavaScript closures work?

Community
  • 1
  • 1
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • No, closures I understand. Check out the edit. SproutCore uses it to allow users to flag functions for caching, data bind, etc... – nicholas Apr 12 '11 at 06:10
0

that's kind'a weird.Maby is was something like :

var module = {
    func : (function(){
        return {func2 : function(v){alert(v);}};
    }).func2('alert me');
}

you cannot chain function definitions (function func (){}.func1()),only function calls (if configured properly) that would look like : func1().func2().func3().....

gion_13
  • 41,171
  • 10
  • 96
  • 108
  • Ah, but you can it would seem. I just don't get how. Example at: http://guides.sproutcore.com/html_based.html#defining-your-model. I would assume they were looping the code through some kind of preprocessor, but I've seen this in a few places now. – nicholas Apr 12 '11 at 06:12
  • In pure javascript,that would trigger an error. If you want to use an interpretor for you own language and then translate it into javascript, almost anything is possible.Just take a look at how processing works. It uses the processing(mainly C) language with all the classical declaration types : `int a;`,`char b;`,`void main(){}`,which in pure js would trigger errors, but it is first interpreted and then translated into javascript, so everything works fine. Although it is possible, it's abit of a headake to go through all that just for a slick synthax. – gion_13 Apr 12 '11 at 06:29
  • I'd agree. I've just seen this syntax in so many places now that I assume there's some trick to it. Extending Function's prototype, or Function's constructor's prototype... – nicholas Apr 12 '11 at 06:35
  • This answer is misleading. Of course you can call a function on a function expression. The only caveat is that the operator precedence rules forces parenthesis around the function. The `new` keyword is not needed at all (and would change the program altogether!). Working example: `(function() { return 1 + 2; }).toString()` – Jakob Apr 12 '11 at 07:37
  • @Jakob You're right, got a bit carried away with the oop part. the thing is that you cannot call a function on a function expression, but you can call it on a function result (if that result is an object that holds that function) – gion_13 Apr 12 '11 at 07:46
  • @gion: see answer above. You can call a function on a function expression if you extend Function's prototype. So `var fn = function() { ... }.foo();` is valid as long as you have `Function.prototype.foo = function() { ... };` in there somewhere. Very different thing than calling a function on the result of a function, as you're example does. – nicholas Apr 12 '11 at 08:16