Javascript - Difference between `this` and `self`

Asked

Viewed 3,906 times

12

I would like to understand and help the community with information.

What’s the difference in the use of this and self in Javascript?

Basically: What? Why use? How to use?

  • Has some context?

  • 1

    Who wants to use as a reference, giving due credits, http://stackoverflow.com/questions/16875767/difference-between-this-and-self-in-javascript

  • Virgilio, is right in the direction of what Marcelo said. Or still: https://developer.mozilla.org/en-US/docs/Web/API/Window/self

1 answer

15


The this can be anything, depending on where it was applied, it’s used along with classes in Javascript and prototype to refer to the object, if it is not an object then two situations may occur:

  • In browsers this assumes the value of window
  • In Node.js this assumes the value of global

For example:

function Foo() {
    alert(this);
}

//Chama como função
Foo(); //Retorna [object Window]

//Chama como classe
new Foo; //[object Object]

The self is equivalent to window.self and is used only in browsers, in the case with self you take the current window/tab, or current frame/iframe and can compare with parent (even though window.parent), the parent in this case it takes the scope of the page that is the parent of the current one if it is in a <iframe> for example, otherwise parent and self will have the same value.

The values you can use to compare the window are:

  • window.self returns the current window object

  • window.parent returns the object of the parent window if any, otherwise the value will be equal to that of self

  • window.top returns the window object above all, for example if a page has an iframe called #frame1 and this iframe has another iframe called #frame2, then in #frame2 use window.top it will return the page object that embarked the #frame1

An interesting example that you can apply the self would be to check if an external site is embedding any of its page, then do something like:

if (window.top !== window.self) {
    window.top.location.href = window.location.href;
}

If the tab or window is not the same as self then it is because your page is embedded in another page, may be on your site or not, then the site that has uploaded a page from you will be redirected to your site/page, of course it is just an example code, there are other ways to block boarding in modern browsers, such as controlling X-Frame-Options or Content-Security-Policy.

Web Worker

An important detail is that in Webworkers we also have the self, but it does not access the window, it is used similar to the this, but instead of taking the scope of one of a class or prototype, it takes the scope of the current Webworker.

The this also picks up Worker’s scope, but if the this is inside a class inside Worker it will not catch the Worker but the "object" of the class, for example:

On the page:

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<script type="text/javascript">
var worker = new Worker('webworker.js');

worker.addEventListener('message', function(e) {
    alert('Worker respondeu: ' + e.data);
}, false);

function sayHello()
{
    worker.postMessage('oi, tudo bem?'); // Envia mensagem ao werbworker.js
}

function sayTchau()
{
    worker.postMessage('tchau'); // Envia mensagem ao werbworker.js
}
</script>

<button onclick="sayHello();">Diga Oi!</button>
<button onclick="sayTchau();">Diga Tchau!</button>
</body>
</html>

Within the webworker.js

this.addEventListener('message', function(e) {
    switch (e.data) {
        case 'oi, tudo bem?':
            this.postMessage('Tudo sim :)'); // Envia resposta para a página de "saudação"
        break;
        case 'tchau':
            this.postMessage('Tchau, até mais'); // Envia resposta para a página de "despedida"
        break;
    }
}, false);

But if I do this, it won’t work, because this will no longer be the scope of Worker:

function Classe()
{
    this.addEventListener('message', function(e) {
        switch (e.data) {
            case 'oi, tudo bem?':
                this.postMessage('Tudo sim :)'); // Envia resposta para a página de "saudação"
            break;
            case 'tchau':
                this.postMessage('Tchau, até mais'); // Envia resposta para a página de "despedida"
            break;
        }
    }, false);
}

new Classe;

Then it would be better this way:

function Classe()
{
    self.addEventListener('message', function(e) {
        switch (e.data) {
            case 'oi, tudo bem?':
                self.postMessage('Tudo sim :)'); // Envia resposta para a página de "saudação"
            break;
            case 'tchau':
                self.postMessage('Tchau, até mais'); // Envia resposta para a página de "despedida"
            break;
        }
    }, false);
}

new Classe;
  • 1

    Guilherme Nascimento. The inclusion of the example in Webworker was top. Thank you.

  • @Brunoheringer updated the answer ;)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.