0

I recently search in the code of the library of knockout to find how observables are able to create dependencies with computed functions when we call it.

In the source code, I found the function linked to observables creation:

ko.observable = function (initialValue) {
    var _latestValue = initialValue;

    function observable() {
        if (arguments.length > 0) {
            // Write

            // Ignore writes if the value hasn't changed
            if (observable.isDifferent(_latestValue, arguments[0])) {
                observable.valueWillMutate();
                _latestValue = arguments[0];
                if (DEBUG) observable._latestValue = _latestValue;
                observable.valueHasMutated();
            }
            return this; // Permits chained assignments
        }
        else {
            // Read
            ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
            return _latestValue;
        }
    }
    ko.subscribable.call(observable);
    ko.utils.setPrototypeOfOrExtend(observable, ko.observable['fn']);

    if (DEBUG) observable._latestValue = _latestValue;
    observable.peek = function() { return _latestValue };
    observable.valueHasMutated = function () { observable["notifySubscribers"](_latestValue); }
    observable.valueWillMutate = function () { observable["notifySubscribers"](_latestValue, "beforeChange"); }

    ko.exportProperty(observable, 'peek', observable.peek);
    ko.exportProperty(observable, "valueHasMutated", observable.valueHasMutated);
    ko.exportProperty(observable, "valueWillMutate", observable.valueWillMutate);

    return observable;
}

What I think is very weird is the returns of 'observable' where I don't found any declaration of this variable. Sure that great men who created this library don't forget to declared it.

How it is possible to use a variable without declared it and prevent it to be put in a global scope?

My feeling is we can used a function declaration as a variable when this function declaration is declared inside another function but I'm really not sure about how it works.

Edit: After searching on the web, I found this article.

In this article, the guy write this:

Use declarations, please "In the code of unexperienced developers, functions are often declared by expressions:

... code ... var f = function() { ... } ... Function Declarations are much more readable and shorter. Use them instead.

... code ... function f() { ... } ... Besides, functions declared this way can be called before it’s definition.

Use expressions only if you mean it. E.g for conditional function definition."

Ok, Am I an unexperienced developer? I don't think so. I just don't read all the odds of Javascript. :)

Samuel
  • 12,073
  • 5
  • 49
  • 71
  • 1
    The author of the article who said `in the code of unexperienced developers` seems to have a bit of an inferiority complex, or something, and is trying to prove his level of experience and intelligence. `var f = function() { }` and `function f() { }` are both valid and each have their own unique pros and cons. But to suggest that one syntax is only found in the code of `unexperienced` developers while the other is the `correct` way to declare a function is just silliness. – Adam Jenkins Nov 29 '14 at 01:07
  • 1
    Javascript is a rather idiosyncratic language, so it's easy to be an experienced dev but unexperienced at javascript. As far as JS devs are concerned, though, this is not a particularly obscure style. To me, having a strong preference one way or another indicates a degree of discomfort with the language. `var f = function () { }` is beloved by those uncomfortable with implicit hoisting, and `function f() {}` is favored by those uncomfortable with thinking of functions as values. After a while, you don't even see the code. All I see is blonde, brunette, redhead... – Chris Martin Nov 29 '14 at 01:45

2 Answers2

2

observable is a variable. It is declared by a function declaration.

function observable() {
    ...
}
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
  • I always thought that a function declaration could just be called but not used by itself as a variable. I mean, you declare a function and then call it. Or you declared a variable and assign it the function declaration which will create a function declaration and then returns the variable. But in all cases, not simply used a function declaration like a variable. Weird... – Samuel Nov 29 '14 at 00:53
  • 2
    @Samuel Nope, functions are all just values that can be assigned to variables, regardless of how they're declared. The only special caveat about named functions is how they're hoisted (see [the link](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)). – Chris Martin Nov 29 '14 at 00:57
  • @LightnessRacesinOrbit The attribute of `observable` named `valueHasMutated` is assigned by the statement starting with `observable.valueHasMutated = ...`. – Chris Martin Nov 29 '14 at 01:00
  • @ChrisMartin: Oh, yes, true. This code _is_ kinda weird to read. – Lightness Races in Orbit Nov 29 '14 at 01:13
0

In Javascript, functions can also be returned. Within the function, he defines the function "observable" which is returned at the end of the function.

Sort to speak, functions are variables too. With a function inside.

Desaroll
  • 323
  • 1
  • 9