2

I am trying to learn more about Javascript, I have been coding with PHP and making web application for years, I have basic knowledge of JS, most of the JS I have used has been already coded and me just plugging it in until recently, in the past years I have been able to do a lot with jQuery.

I have noticed that Stack Overflow uses jQuery more then most sites I have seen, it is beautiful all the JS functionality they have here.

So a basic question, Stack Overflow uses StackExchange in front of most of the JS code that I have seen on here. What exactly is that doing? To me I would want to say it is like a Class name but I read JS does not have classes.

Here is an example code

StackExchange.debug.log("no cache breaker for " + q);

Can you break this down for me to explain what the StackExchange, debug, log are? I mean I can tell that log must be a function call but the others?


PS) Please don't move this to META as it is a JS question and not specific to StackOverflow Also feel free to edit the question title and delete this line if you can think of a better title, thanks

JasonDavis
  • 48,204
  • 100
  • 318
  • 537

5 Answers5

6

Think of StackExchange as something much like the global jQuery function, "$" (or "jQuery"). It's just a global reference to an object that has functions and other properties.

Thus, "debug" is a property of the global "StackExchange" object, and in turn "log" is a property of the "debug" object. In this case, the "log" property references a function, which clearly is a debugging tool.

It's a debatable point whether JavaScript has "classes" or not, but it definitely has objects. (By "debatable" I mean it's a subject that fills an endless stream of blog posts and Stackoverflow questions :-)

That is, in fact, basic JavaScript. There's nothing super fancy or tricky about it.

Pointy
  • 405,095
  • 59
  • 585
  • 614
3

Namespaces.

this may be relevant

How do I declare a namespace in JavaScript?

Community
  • 1
  • 1
Sid Malani
  • 2,078
  • 1
  • 13
  • 13
2
EDITED FOR CLARIFICATION

Before I say ANYTHING, please see How Classical Object-Oriented Programming Translates to Javascript. This is VERY important to understand. Now, that being said, I'll continue :)

Javascript has the unfortunate characteristic that you have to understand the run-time environment very well in order to make sense of why certain syntax is chosen over another that expresses the same thing (in theory). One of the main caveats of the run-time environment of javascript is that it is very easy to get things into the global space unintentionally. Here's two quick examples (these examples assume that you don't have any other code written):

    /*
     * Example 1
     * This example uses 'object literal notation'.
     * A link to an article about this is below the example.
     * This example shows how easy it is to get into the global space just by
     * not declaring variables properly. 
     */
    var myObj = {
        myMethod: function() {
            test = 'test';  // oops! now the variable test is in the global
                            // function space :(
                            // to avoid this, use var test = 'test'; to keep 
                            // test in the scope of myMethod
        }
    };

Read about object literal notation.

    /*
     * Example 2
     * This example shows how the infamous 'this' can be misused to accidentally
     * get into the global space.
     */
    var myConstructor = function() {
        this.test = 'test';
    };
    var myObj1 = new myConstructor();  // 'this' will by 'myObj1'
    var myObj2 = myConstructor();  // 'this' will by the global object :(

To see why Example 2 is true, see this.

One of the ways you avoid all of these headaches is by following good patterns that control access to the global scope. As some of the answers have pointed out, you can think of the StackExchange object as being used for namespacing purposes, but in reality, it's most often used to also avoid the problem listed in above example, as well prevent things such as name hoisting. In addition, you can make this 'namespacing' object also behave more like a traditional object from other classical OOP languages if you are intelligent in using closure scopes (taking advantage of the fact that all scopes in javascript are bound to functions, and functions in javascript are first-class data objects). Also, because the global space is so dangerous, it's best to "be a good DOM citizen" and only create one object in the global space that encapsulates all of your logic and data.

Joel and jeff are probably actually setting up closure scopes to do information hiding the javascript way. The below is just an example:

   StackExchange = (function() {  // give StackExchange it's own scope to prevent
                                  // name hoisting and also to allow for private
                                  // data
       var version = '1.0.0';  // version only seen inside function scope
       return {  // return an object that will become 'StackExchange' and whose
                 // methods have access to this function's scope (closure)
           debug: (function() {
               // set up logging function that will be determined based on
               // 'someCondition' (not defined in this code)
               var loggingFn = (someCondition) : console.log ? alert;
               return {  // return obj with access to this function scope
                   log: function(strToLog) {
                       loggingFn.call(this, strToLog);
                   }   
               };    
           })(),  // immediately execute to make object with 'debug' scope access
           getVersion: function() {
               return version;  // this function has access to StackExchange
                                // scope; therefore, version will be available
           }
       };
   })();  // immediately execute to make object with 'StackExchange' scope access

For more information, see name hoisting and scoping. Also, please read about Prototypical Inheritance in Javascript to understand patterns used to avoid global scoping problems.

Ryan
  • 1,557
  • 9
  • 11
  • thanks for example, I am pretty confused, with my php experience I am familiar with "namespace -> class -> function or property" I could relate this a little bit to that but I have a lot to learn. things like the syntax, I have seen javascript functions defined and called several different ways, as if there is no standard syntax (i'm sure there is, just what my basic JS knowlege is allowing me to see) – JasonDavis Nov 20 '11 at 17:08
  • I am curious, how many levels deep can it go? And `StackExchange = {}` why does `debug: {}` have the `":"` and the other doesn't? – JasonDavis Nov 20 '11 at 17:12
  • So, first, you're right, there are a lot of ways to express things in javascript. Mainly, this is due to the fact that, in JS, you have to be more aware of the runtime environment than most other languages whenever you write something. – Ryan Nov 20 '11 at 17:29
  • The ":" is used when you are using "object literal notation", i.e., the most succinct way to notate the creation of an object in JS. For example, in my example, I used `return { debug: ..., getVersion };` The `{ ... }` is 'object literal notation'. It has the format: `{ : , : , ... }`. Give me a few minutes, and I will try to clean up my answer to make it (hopefully) easier to work with :) – Ryan Nov 20 '11 at 17:32
  • And it can go infinitely deep in levels (responding to your first question). – Ryan Nov 20 '11 at 17:38
1

This code would define the object necessary to perform the call shown in your example. As you can see, it simply defines an object containing more objects finally containing one or more functions.

var StackExchange = {
    debug: {
        log: function(whatever) { /* some code */ }
    }
};

StackExchange.debug.log("no cache breaker for " + q);
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
1

StackExchange is a global object and debug is an another object which is a property of StackExchange object and it has a function called log.

Read more about Objects in JavaScript here.

pradeek
  • 21,445
  • 2
  • 31
  • 32