2

If I create an Object as follows:

window.Something = {
    X: function() {
        // statements...
    }
};

What is the best way to access this object without using this?

Example:

If I call the X property by using:

window.addEventListener("DOMContentLoaded", window.Something.X);

In this case using this will access window and not Something. I thought at this method but I think it is a bad practice.

window.Something = {
    X: function() {
        var This = window.Something;

        // statements...
    }
};

There is an implicit way to always access the real object that created the property?

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304

4 Answers4

2

If I'm understanding your question correctly, then you probably want to use bind:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

To do something like this:

window.addEventListener("DOMContentLoaded", Something.X.bind(Something));

This will ensure that within the call to Something.X, this points to Something.

More useful info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

Ben Jackson
  • 11,722
  • 6
  • 32
  • 42
  • I think that there is no no need for bind, this will be set to "Something" anyway, also no need for window, if created in the global context it doesn't matter. – Vitaliy Terziev Nov 24 '15 at 15:21
  • 2
    @vtz No, `bind()` or something similar is needed. In the context of an event handler, `this` will *not* be the object containing `X`, it will be the object on which the event was fired (`window`, in this case). – Paul Roub Nov 24 '15 at 15:22
  • I do not agree, you can check my answer below, ofcourse if i am mistaken i will gladly remove my answer @PaulRoub – Vitaliy Terziev Nov 24 '15 at 15:28
  • 1
    You added a wrapper function. That would be the "something similar" I mentioned. `bind()` eliminates the need for that here. – Paul Roub Nov 24 '15 at 15:34
  • I stand corrected, i will change my answer and will remove bind(), thanks @PaulRoub – Vitaliy Terziev Nov 24 '15 at 15:37
2

Use bind() to call the handler with the appropriate this:

window.addEventListener("DOMContentLoaded", window.Something.X.bind(window.Something));
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
2

Nobody has pointed out why this is occurring.

According to MDN:

When attaching a handler function to an element using addEventListener(), the value of this inside the handler is a reference to the element. It is the same as the value of the currentTarget property of the event argument that is passed to the handler.

In other words, this refers to the window object because the event listener is attached to the window object. For instance, if you attached the event listener to an input element, this.name would refer to the name attribute of the input element that the event was attached to.

Example Here

window.Something = {
  name: 'Some name',
  X: function() {
    console.log(this.name); // 'test'
  }
};

document.getElementById('target').addEventListener('input', Something.X);
<input id="target" name="test" />

As others have pointed out, you can either change the value of this by using the bind() method:

Example Here

window.Something = {
    name: 'Some name',
    X: function () {
        console.log(this.name); // 'Some name'
    }
};

window.addEventListener("DOMContentLoaded", Something.X.bind(Something));

Alternatively, you could also just execute the X method inside of an anonymous function. This will prevent the addEventListener() method from modifying the value of this.

Example Here

window.Something = {
    name: 'Some name',
    X: function () {
        console.log(this.name); // 'Some name'
    }
};

window.addEventListener("DOMContentLoaded", function () {
    Something.X();
});
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
0

There is no need to refer window (windows is always the object when you are declaring variables in the global scope), also you can use bind() or wrapper function. this will refer to the first object in scope. Try the below code

Something = {
    X: function()
    {
        // statements...
        console.log(this);

    }
};
window.addEventListener('click',function(){Something.X()});
Vitaliy Terziev
  • 6,429
  • 3
  • 17
  • 25