14

If my code looks like this, what is the preferred method of using var vs this?

function MyObject() {
    var self = this;

    var a = 1;
    this.b = 2;

    var innerMethod = function() {

        logMessage(a); 
        logMessage(self.b); 
    }
}

As I understand, var will survive as long as MyObject lives, so isnt this the same as using this?

EDIT:

To clarify the question more, I am ONLY interested in accessing variables from inside the object, not from outside.

Toniq
  • 4,492
  • 12
  • 50
  • 109
  • You probably want to check: http://stackoverflow.com/questions/3564238/object-oriented-javascript-with-prototypes-vs-closures – phadej Dec 21 '14 at 12:53
  • check the link to understand THIS with more clarity https://scotch.io/@alZami/understanding-this-in-javascript – AL-zami Sep 10 '17 at 19:14

4 Answers4

18

with var a you cant access the variable outside the scope however assigning with this can be accessed when you make an object

We add properties to this when we want the properties to exist with the life of the object.We Use var for local variables.

"I am ONLY interested in accessing variables from inside the object, not from outside."

Answer to this statement is use var if you want to use only inside the function not outside as variable defined with var are accessible only to code in the scope in which they were declared, or in lexically nested scopes.

so as Shomz suggested you can check it as:

var o = new MyObject();

a will be undefined as it is defined with var

  o.a; // undefined

while b will be return 2 as it is on this

 o.b; // 2
A.B
  • 20,110
  • 3
  • 37
  • 71
8

If you define a variable as var, then its scope is limited to the function (it can't be seen from the outside). In OO terms it's somehow like a private property, without actually being a property at all.

If you define a variable as a property (this.name) then it is accessible from the outside.

Same goes for functions. Functions declared inside the scope of the function, but not assigned to a property, are only visible from the inside. If you assign a function to a property you are able to access that function from the outside (as long as the property keeps pointing to that function).

function Person(){

    // Declared variable, function scope
    var name = "John";          

    // Property        
    this.surname = "Doe";       

    // Assign anonymous function to property
    this.getName = function(){  
        return name;
    }

    // Assign anonymous function to property
    this.getSurname = function(){ 
        return this.surname;
    }

    // Declare function
    function saluteCasually(){      
        console.log("Hi folks!");
    }

    // Declare function
    function salutePolitely(){          
        console.log("Nice to meet you");
    }

    // Assign (not anonymous) function to property
    this.salutePolitely = salutePolitely;

}

var person = new Person();

console.log(person.name);           // undefined
console.log(person.getName());      // "John"
console.log(person.surname);        // "Doe"
console.log(person.getSurname());   // "Doe"

person.saluteCasually(); // Error: person has not a property "saluteCasually".
person.salutePolitely(); // Prints "Nice to meet you";

person.salutePolitely = function(){ // Properties can be messed with from anywhere!
    console.log("Bananas");
}
person.salutePolitely(); // Prints "Bananas";
abl
  • 5,970
  • 4
  • 25
  • 44
  • Why would you do this? this.salutePolitely = salutePolitely; instead of directly this.salutePolitely = function(){ } – Toniq Dec 21 '14 at 13:28
  • @Toniq I think it has at least three (perhaps subjective) advantages. (1) Named function is accessible from the scope of the constructor even if value of property gets changed from outside. (2) Code in constructor is a bit cleaner since you don't have `this` or `self` all over the place. (3) Code in constructor is cleaner because you visually separate the implementation of the function from whether it is public or not. First you define all the functions, then you assign only the public ones to properties, so at a glance you can easily see what is public and what is not. – abl Dec 21 '14 at 13:39
  • what will be the scope of function saluteCasually? – ssal Jul 10 '15 at 19:32
  • @ssal The scope of the function `saluteCasually()` is limited to the function it is declared in, `Person`. All the code within `Person()` can see `saluteCasually()`. Note that a new "instance" of the function `saluteCasually()` is created every time that `Person()` is invoked. – abl Jul 10 '15 at 19:53
3

It depends on what you want , using a VAR inside the function will not make it accessible outside the function scope , but from a performance perspective if you are using objects keep everything inside of it , you have already stored this object in the memory why define another variable again .

as said in the Memory Analysis 101 form chrome devtools documentation :

Memory can be held by an object in two ways: directly by the object itself, and implicitly by holding references to other objects, and thus preventing them from being automatically disposed by a garbage collector (GC for short).

The size of memory that is held by the object itself is called shallow size. Typical JavaScript objects have some memory reserved for their description and for storing immediate values.

Usually, only arrays and strings can have significant shallow sizes. However, strings often have their main storage in renderer memory, exposing only a small wrapper object on the JavaScript heap.

Nevertheless, even a small object can hold a large amount of memory indirectly, by preventing other objects from being disposed by the automatic garbage collection process. The size of memory that will be freed, when the object itself is deleted, and its dependent objects made unreachable from GC roots, is called retained size.

Devtools Docs

Hasan Al-Natour
  • 1,936
  • 2
  • 14
  • 22
  • This is probably the best answer. – Shomz Dec 21 '14 at 13:08
  • 1
    So using this is better performance wise? I have no problem with that except the code looks quite messy with prefix self. being everywhere. – Toniq Dec 21 '14 at 13:31
  • its just the same as using var everywhere , i use the prefix "vars" most of the time , so when i see var its a new variable and when i see vars its a variable using this. so its up to you you can make it look messy or look good. – Hasan Al-Natour Dec 21 '14 at 13:34
1

If you want to use properties once you instantiate the object, var won't work, see below:

function MyObject() {
    var self = this;

    var a = 1;
    this.b = 2;

    var innerMethod = function() {

        logMessage(a); 
        logMessage(self.b); 
    }
}

var o = new MyObject();
console.log(o.a); // undefined
console.log(o.b); // 2
Shomz
  • 37,421
  • 4
  • 57
  • 85