4

I have been doing some JavaScript development and I encountered this problem. Consider the following code

var obj = {};
obj.bind = function () {
console.info(this);
};

obj.bind();

I'm running the code on the FireBug JavaScript console. The expected result is that this displays a reference to the object in the console.

It actually displays undefined.

But, when I make this change to my code

var obj = {};
obj.bind = function () {
this.x = 'x';
console.info(this);
};

obj.bind();

Now the console displays the expected value of this, which is a reference to the obj object.

Why does this happen?

4
  • 3
    I tried the first example in Chrome's developer console and it displayed the object as you expected. Perhaps this is a bug in Firebug? Commented Jul 13, 2011 at 1:24
  • 1
    The console can lie about a few things, keep that in mind. An example is deleting variables with delete. Works in the console, not outside. Commented Jul 13, 2011 at 1:25
  • @Jeremy No it doesn't. It displays 'undefined'. Chrome displays the object, but that's because Chrome does, and not because of the 'console.info' function. Look under the object and you'll find the undefined word. Commented Jul 13, 2011 at 1:34
  • @Omar You're incorrect. Append some string to this before writing it out in in obj.bind to confirm this yourself. I think the undefined it displays is the return value of the obj.bind() call. Commented Jul 13, 2011 at 1:38

2 Answers 2

3

undefined is the return value of the function, which you'll get because you're not returning a value explicitly.

In both Chrome and Firebug, it correctly displays the Object in the console before the return value undefined.

So if you do:

var obj = {};
    obj.bind = function () {
    console.info(this);
    return "foo";
};

obj.bind();

...you should see something like:

Object {   }
"foo"

If Firebug is not displaying the Object when it is empty, you may need to check to make sure you're using the most current version.

Sign up to request clarification or add additional context in comments.

Comments

-1

In your example, "this" should be obj, just as some commenters pointed out. Here are the details that explain why --

In Javascript, the value of "this" changes depending on how you call the function:

  1. When a function is stored as a property on an object, and you invoke that function by calling obj.foo(), "this" will be obj.

EX:

var obj = {
  x: 1,
  increment: function() {
    this.x = this.x + 1;
};

obj.increment(); // Makes "this" be obj
  1. When you invoke a function using syntax that does not refer to any owning object, "this" will be the global environment.

EX:

function someFunc(a, b) {
     return a + b; // If you were to refer to "this" here, it would be the global env.
}

someFunc(5, 6);
  1. When you invoke a function as if it were a constructor by using the new operator, a new object will be instantiated for you, and "this" will point to that new object.

EX:

function SomeConstructor() {
   this.x = 42; // under the hood, a new object was instantiated for you, and "this" was set to it.
}

var result = new SomeConstructor(); // note the "new" keyword

// result will be { x:42 }

  1. When you use call() or apply(), you can control what "this" is.

(No example here since it's fairly far from your question. Look up docs for apply() or call() for an example.)

2 Comments

Except in ES5 strict mode, where if this does not resolve to an object, it is left as–is, it is not set to the global object as it would be otherwise (ES5 §10.4.3).
Anybody want to explain the downvote? I sure don't see what's wrong, but if something is, I'd like to fix it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.