2

I know this is kind of a silly example-- but why does this code result in an error that bar is not defined. Wouldn't javascript look to see if bar was a property of "this" object. I know that adding this, fixes the problem-- but this tends to throw me off. In other programming languages (C#) for instance, this is usually redundant-- why does it need to be added in the code below?

   var myObject = {
        foo : function(){
            alert(bar);
        },
        bar : "hello world"
    };

    myObject.foo();

http://jsfiddle.net/Mv86n/

ek_ny
  • 10,153
  • 6
  • 47
  • 60
  • you need to read about the javascript scope chain and how it traverses it looking for objects. – Modika Nov 19 '12 at 20:50

7 Answers7

1

Because, as you have demonstrated, JavaScript does not start variable lookups with this.

Community
  • 1
  • 1
Matt Ball
  • 354,903
  • 100
  • 647
  • 710
1

Wouldn't javascript look to see if bar was a property of "this" object

No. It looks at what variables are in scope, not what properties are members of the current context.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

Javascript has function scope, not object scope.

Only identifiers declared within the same function is in the local scope, everything else is accessed from the global scope.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
1

It just doesn't work that way. It could have, but the language designers probably thought that that way would lead to inefficiencies, ambiguities and code that it hard to see what is going on.

I'll admit that I am also sometimes annoyed by the necessity of prepending "this." onto things, and even more annoyed that I am constantly having to say "var self = this;", but such is life in Javascript. You just have to accept it for what it is, and move on.

rob
  • 9,933
  • 7
  • 42
  • 73
0

Think of it this way:

var myObject = {
    foo : null,
    bar : "hello world"
};
myObject.foo = function(){
    alert(bar);
}

Now, what is bar supposed to refer to? As you can see more easily now, bar is not in scope.

In C#, methods belong to objects and it is known what attributes they have, which is why such a thing is possible. But in JavaScript, you don't have that knowledge, "methods" don't belong and attributes are dynamic, which makes such scoping rules unfeasible.

phant0m
  • 16,595
  • 5
  • 50
  • 82
0

In javascript, the lookup priority is ancestor functions scopes (which can be nested, unlike in C++ and Java) from the nearest of the code beiing executed to the farthest.

On that trivial example, it looks like having an implicit this would make sense, but it would be much more complicated to specify and used with different levels of nested functions and object.

(function() {
    var myVar = "dsjsh";
    return {
        myVar: "var",
        myMethod: function() {
            /* which */ myVar;
        };
    }
})()

Obviously, the language made the choice of simplicity (at least for this matter).

Samuel Rossille
  • 18,940
  • 18
  • 62
  • 90
0

JavaScript doesn't exactly have a concept of classes or class scope; myObject should be thought of as a map, moreso than an object. For example, you could do this:

function foo() {
    alert(this.bar);
}
var myObject = {
    bar: "hello world"
};
myObject.foo = foo;

In this case, why should foo know about myObject when it's defined? When you call myObject.foo(), JavaScript passes in myObject as this (of course, JavaScript's scoping rules regarding this are kind of strange, so this isn't always what you think it is), and you can access myObject through this. If you just called foo(), this would be something different (in a browser, it would probably be window), and even accessing this.bar wouldn't work.

Adam R. Nelson
  • 541
  • 4
  • 11