3
var zee5 = "Variable Outside";

function magical( ) {
    this.zee5 = "Variable Inside";
    alert( this.zee5 ); 
}

magical();

alert(zee5); 

In the second "alert" I was expecting to see "Variable Outside" but that was not the case. I still got "Variable Inside" which means

this.zee5 = "Variable Inside";

accessed and modified the zee5 variable created at top of the script. I thought this.zee5 would bind the zee5 to the function named magical only.

416E64726577
  • 2,214
  • 2
  • 23
  • 47

2 Answers2

1

This is discussed to death in How does the "this" keyword work?. In particular, the see the f1 example at the top of this answer.

Summarizing the immediately relevant part of the linked answer:

function f() { return this; }
f() === window // -> true

Now, the issue about "variable scoping" is an addition to those answers, but it can be summed up as this: variables in the global context are properties of the global object.

var x = "hello";
window.x = "world";
x // -> "world"

So this.zee5 = .. in context is the same as window.zee5 = .. and per above it overwrites the global variable/property ..

To write to a property of the function-object known as magical, simply use

var zee5 = "hi"
function magical()
{
   magical.zee5 = "hello"
}
magical()
zee5          // -> "hi"
magical.zee5  // -> "hello"

One could of course get "sneaky" so that this was bound to magical inside the function invocation, e.g. magical.apply(magical) or magical = magical.bind(magical), but I digress..

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
1

In the above case "this" keyword still refers to the outside context, so if you execute the above code at the root scope for instance, this refers to window. So you're actually just setting a property called "zee5" on the window.

You can console.log(this) anywhere in your code to see what it's pointing to.

If you want to bind the property to a function, you could do something like below, and assign the function to a variable rather than use a function declaration.

E.g. if you changed the code to the below it might work as you think:

var zee5 = "Variable Outside";

var magical = function(){
alert( this.zee5 ); 
}
// sets property zee5 on the variable magical
magical.zee5 = "Variable Inside";
// will alert the property set on magical
alert(magical.zee5)
// when the below executes, "this" still refers to window
magical();
// implicitly calling window.zee5, if done from root context
alert( zee5 );

But I think what you might be doing is confusing the way new objects are declared in js. For example if you did the following, changing the approach to use the function declaration as a constructor, then the context will change to the object you've just declared and you'll also get what you're expecting:

var zee5 = "Variable Outside";

function magical( )
{
this.zee5 = "Variable Inside";
alert( this.zee5 ); 
}
// will create an object of type magical
// this refers to the new object inside the constructor function
var mag = new magical(); 

alert( zee5 );
Greg Jennings
  • 1,611
  • 16
  • 25