views:

144

answers:

2

What is the difference between these?

var a = 13;  
this.b = 21;  
document.write(a);  
document.write(b);
+1  A: 

To understand in short, if you use these in a function then -

this.a; //will create a public property

var b; //will create a member variable

e.g. here is a Student class in javascript

var Student = function()
{
    // Member variable
    var studentId;

    // Public property
    this.Name = "";
}

for more - See Object Oriented Programming with JavaScript

Ramesh Soni
Dang, just beat me by 5 secs
Jason Jong
+13  A: 

For global code (code that is not part of any function), they are almost equivalent, both at the end create a property on the global object.

The difference is that a, which has been declared with the var statement, the Variable Instantiation process will use the global object as the Variable Object (1), and it will define that property as non-deleteable on it, e.g.:

var a = 13;
delete a; // false
typeof a; // "number"

Then, b since the this value in global code, points to the global object itself, will be also a global property, but this one can be deleted:

this.b = 21;
delete b; // true
typeof b; // "undefined"

Don't try the first snippet in Firebug, since the Firebug's console runs the code internally with eval, and in this execution context the variable instantiation process behaves differently, you can try it here.

(1) The Variable Object (VO) is an object that is used by the variable instantiation process to define the identifiers of FunctionDeclarations, identifiers declared with the var statements, and identifiers of function formal parameters, in the different execution contexts, all those identifiers are bound as properties of the VO, the Scope chain is formed of a list of VO's.

For global code, the VO is the global object itself, that's why a ends being a property of it. For function code, the VO (also known as the Activation Object for FunctionCode), is a new object is created behind the scenes when you invoke a function, and that is what creates a new lexical scope, in short I'll talk about functions.

Both a and this.b can be resolved simply as by a and b because the first object in the scope chain, is again the global object.

Also, I think is work knowing that the Variable Instantiation process takes place before than the code execution, for example:

alert(a); // undefined, it exists but has no value assigned to it yet
alert(b); // ReferenceError is thrown

var a = 13;
this.b = 21;

These differences may be trivial but I think is worth knowing them.

Now, if the code snippet you posted is within a function, it is completely different.

The a identifier, declared with the var statement in your example will be a local variable, available only to the lexical scope of the function (and any nested functions).

Keep in mind that in JavaScript blocks don't introduce a new scope, only functions do, and to declare a variable in that scope, you should always use var.

The this.b identifier will become a property bound to the object that is referred by the this value, but... What is this???.

The this value in JavaScript is implicitly set when you call a function, it is determined by how do you invoke it:

  1. When you use the new operator, the this value inside the function, will point to a newly created object, e.g.:

    function Test() {
      this.foo = "bar";
    }
    var obj = new Test(); // a new object with a `foo` property
    
  2. When you call a function that is member of an object, the this value inside that function will point to the base object, e.g.:

    var obj = {
      foo: function () {
        return this == obj;
      }
    };
    obj.foo(); // true
    
  3. When you invoke a function without any base object, the this value will refer to the global object:

    function test() {
      return this == window;
    }
    test(); // true
    
  4. The this value can be set explicitly, when you invoke a function using call or apply:

    function test() {
      alert(this);
    }
    test.call("hello world!"); // alerts "hello world!"
    
CMS
+1 Just for this clear explanation, I checked your profile to see if you had a blog that I could read :)
Konerak
+1 for full very nice answer
Anil Namde
+1 for a good explanation, but your first line is somewhat inaccurate: a global variable is not the same thing as a property of the global object, as you then go on to show. That declaring a variable with `var` in the global scope creates a property of the global object is a *side-effect* of the fact that the global object is used as the Variable object in the global scope.
Tim Down
@Tim, agree, edited to clarify, thanks! :)
CMS