JavaScript - Difference between 'this' and 'self'

9

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

What's the difference between using this and self in JavaScript?

Basically: What? Why use? How to use?

    
asked by anonymous 03.05.2017 / 01:58

1 answer

12

The this can be anything, depends on where it was applied, it is used together with classes in JavaScript and prototype to refer to the object, if it is not an object then two situations occur:

  • In browsers this takes the value of window
  • In Node.js this takes 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]

self is equivalent to window.self and is used browsers only , in case with self you get the current window / tab, or frame / iframe and can compare with parent (even window.parent ), parent in this case takes the scope of the page that is the parent of the current if it is in <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 parent window object if it exists, otherwise the value will be equal to self

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

An interesting example that you can apply self would be to check if an external site is uploading some page of yours, 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 your page is embedded on another page, it may be on your site or not, then the site that uploaded your page will be redirected to your site / page, of course it's just an example code, there are other ways to block embark on modern browsers, such as by controlling X-Frame-Options or Content-Security-Policy .

Web Worker

An important detail is that in WebWorkers we also have self , but it does not access the window, it is used similar to 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 takes the scope of the Worker, but if the this is inside a class in Worker it will not get the Worker but the "object" class, for example:

On 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 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 you do this it will not 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;
    
03.05.2017 / 02:04