2

This code from ryan niemeyer on this blog bost declares an empty function(named result) and then adds properties to the function:

ko.dirtyFlag = function(root, isInitiallyDirty) {
    var result = function() {},
        _initialState = ko.observable(ko.toJSON(root)),
        _isInitiallyDirty = ko.observable(isInitiallyDirty);

    result.isDirty = ko.computed(function() {
        return _isInitiallyDirty() || _initialState() !== ko.toJSON(root);
    });

    result.reset = function() {
        _initialState(ko.toJSON(root));
        _isInitiallyDirty(false);
    };

    return result;
}; 

What advantage does this serve over simply creating an object and assigning the same properties before returning the object?

edit

in response to the comment requesting how i would expect it to look: either declaring

var result={};

in the declarations, or as a style thing:

ko.dirtyFlag = function(root, isInitiallyDirty) {
    var _initialState = ko.observable(ko.toJSON(root)),
        _isInitiallyDirty = ko.observable(isInitiallyDirty);
    return {
      isDirty : ko.computed(function() {
        return _isInitiallyDirty() || _initialState() !== ko.toJSON(root);
      }),
      reset : function() {
        _initialState(ko.toJSON(root));
        _isInitiallyDirty(false);
      }
   };
}; 

but the semantics are irrelevant - what does a shell of a function returned provide to the consuming code/developer calling the function?

6
  • In JavaScript functions are objects! Commented May 28, 2015 at 10:52
  • I am aware functions are objects in JavaScript, and therefore the code is legal javascript, but the question is - why not use a simple object? I am positive a programmer of Ryan Niemeyer's repute has a reason for doing this. Commented May 28, 2015 at 10:54
  • I am unclear as to what you are asking. Are you asking why the author isn't returning an object or why they are declaring a function in a certain way? If the latter, can you provide an example of how you expected the code to look? Commented May 28, 2015 at 10:55
  • It has the advantage, that you can call the result (result()) without triggering a runtime error. Commented May 28, 2015 at 10:55
  • 1) why would you want to call result() ? two creating the object via var result = {} would give you the exact same thing, I believe this is just a style preference. Commented May 28, 2015 at 10:58

2 Answers 2

5

In the link you posted, the author states

When ko.toJS runs, it will just see a plain function and ignore it.

In other words, he is using the fact that the framework he is using will ignore functions in the context where he is using it, whereas if he had used an object the framework would not ignore it.

He never intends to call the function, just to use it as a place to store his dirty flag while tricking the knockout framework into ignoring it.

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

2 Comments

interesting! Haven't used knockout.. what does ignoring the object give you? and why would knockout ignore an objected created that way and not var x = {} ?
I don't really know knockout either, just going by what the post author states. Sounds like the framework is iterating the properties of an object and taking an action on each one, but it skips functions (probably because they may be methods). The author uses this fact to hide some state.
1

It's just another way to create an object, I do not believe it has any difference to doing it one way or another. sometimes just a style preference, sometime just the way a programmer likes to do something. (just like using var that = this, or using a function's bind method. both legit and both ways of passing context).

Here is a detailed post on creating objects in JavaScript from MDN

Creating an object and declaring an empty function in JavaScript are way to create an object. In JavaScript things are objects and there are many ways to create them. No one way is much better than the other. Although from ECMAScript5 the better way to do it is Object.create.

2 Comments

Function objects are not totally equivalent to normal objects. For one thing you can't change the prototype of a function object
@harmic what do you mean by that? You can use Object.setPrototypeOf(f, p); with a function object.

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.