Co leży u podstaw tego idiomu JavaScript: var self = this?

Widziałem w źródle dla WebKit HTML 5 SQL Storage Notes Demo :

function Note() {
  var self = this;

  var note = document.createElement('div');
  note.className = 'note';
  note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
  note.addEventListener('click', function() { return self.onNoteClick() }, false);
  this.note = note;
  // ...
}

Autor używa self w niektórych miejscach (ciało funkcji) i this w innych miejscach(ciała funkcji zdefiniowanych w liście argumentów metod). Co się dzieje? Teraz, kiedy już to zauważyłem, czy zacznę to widzieć wszędzie?

Author: DanMan, 2009-06-07

10 answers

Zobacz ten artykuł na alistapart.com

self jest używany do utrzymywania odniesienia do oryginału this, nawet gdy zmienia się kontekst. Jest to technika często stosowana w procedurach obsługi zdarzeń (zwłaszcza w zamknięciach).

 410
Author: Jonathan Fingland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 15:27:51

Myślę, że nazwa zmiennej "self" nie powinna być już używana w ten sposób, ponieważ nowoczesne przeglądarki zapewniają globalną zmienną self wskazywanie na globalny obiekt zwykłego okna lub Webworkera.

Aby uniknąć nieporozumień i potencjalnych konfliktów, możesz zamiast tego napisać var thiz = this lub var that = this.

 93
Author: Duan Yao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-03 11:03:21

Tak, zobaczysz to wszędzie. Często that = this;.

Zobacz jak self jest używany wewnątrz funkcji wywoływanych przez zdarzenia? Mają one swój własny kontekst, więc self jest używany do przechowywania this, które weszły do Note().

Powód self jest nadal dostępny dla funkcji, nawet jeśli mogą one wykonać tylko po zakończeniu wykonywania funkcji Note(), jest taki, że funkcje wewnętrzne otrzymują kontekst funkcji zewnętrznej ze względu na zamknięcie.

 34
Author: Nosredna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 15:35:25

Należy również zauważyć, że istnieje alternatywny wzorzec Proxy do utrzymywania odniesienia do oryginalnego this w wywołaniu zwrotnym, jeśli nie lubisz idiomu var self = this.

Ponieważ funkcja może być wywołana z podanym kontekstem za pomocą function.apply lub function.call, możesz napisać wrapper, który zwróci funkcję, która wywoła twoją funkcję z apply lub call używając podanego kontekstu. Zobacz funkcję proxy jQuery dla implementacji tego wzorca. Oto przykład użycia it:

var wrappedFunc = $.proxy(this.myFunc, this);

wrappedFunc następnie może być wywołana i będzie miała swoją wersję this jako kontekst.

 28
Author: Max,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-01 20:24:46

Zmienna jest przechwytywana przez funkcje wbudowane zdefiniowane w metodzie. this w funkcji będzie odnosić się do innego obiektu. W ten sposób możesz sprawić, że funkcja będzie zawierała odwołanie do this w zewnętrznym zakresie.

 9
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-07 15:02:46

To dziwactwo JavaScript. Gdy funkcja jest właściwością obiektu, trafniej nazywanego metodą, to odnosi się do obiektu. W przykładzie obsługi zdarzenia obiekt zawierający jest elementem, który wywołał zdarzenie. Gdy wywołana jest standardowa funkcja, Ta będzie odnosić się do obiektu globalnego. Jeśli masz zagnieżdżone funkcje, jak w twoim przykładzie, to w ogóle nie odnosi się do kontekstu zewnętrznej funkcji. Funkcje wewnętrzne dzielą zakres z zawiera funkcję, więc programiści będą używać odmian var that = this w celu zachowania tego , których potrzebują w wewnętrznej funkcji.

 9
Author: kombat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-16 20:42:25

Jak wyjaśnili inni, var self = this; pozwala na kod w zamknięcie powrót do zakresu nadrzędnego.

Jednak jest teraz 2018 i ES6 jest szeroko obsługiwany przez wszystkie główne przeglądarki internetowe. Idiom var self = this; nie jest tak istotny jak kiedyś.

Jest teraz możliwe uniknięcie var self = this; poprzez użycie funkcje strzałek.

W przypadkach, w których użylibyśmy var self = this:

function test() {
    var self = this;
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", function() {
        console.log(self.hello); // logs "world"
    });
};

Możemy teraz używać funkcji strzałek bez var self = this:

function test() {
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", () => {
        console.log(this.hello); // logs "world"
    });
};

Funkcje strzałek nie mają własnego this i po prostu przyjmują zakres otaczający.

 6
Author: Elliot B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-30 02:45:50

W rzeczywistości self jest odniesieniem do window (window.self), dlatego kiedy mówisz var self = 'something' nadpisujesz odniesienie do samego okna - ponieważ self istnieje w obiekcie window.

Dlatego większość programistów woli var that = this nad var self = this;

W każdym razie; var that = this; nie jest zgodne z dobrą praktyką ... zakładając, że Twój kod zostanie później poprawiony / zmodyfikowany przez innych programistów, powinieneś używać najbardziej popularnych standardów programowania w odniesieniu do społeczności programistów

Dlatego powinieneś użyj czegoś takiego jak var oldThis / var oThis / etc-żeby było jasne w swoim zakresie / / ..nie jest tak dużo, ale zaoszczędzi kilka sekund i kilka cykli mózgu

 5
Author: SorinN,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-11 08:56:32

Jak wspomniano kilka razy powyżej, 'self' jest po prostu używany, aby zachować odniesienie do 'this' przed wejściem do funkcji. Raz w funkcji " to " odnosi się do czegoś innego.

 0
Author: Cyprien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-27 17:54:13
function Person(firstname, lastname) {
  this.firstname = firstname;

  this.lastname = lastname;
  this.getfullname = function () {
    return `${this.firstname}   ${this.lastname}`;
  };

  let that = this;
  this.sayHi = function() {
    console.log(`i am this , ${this.firstname}`);
    console.log(`i am that , ${that.firstname}`);
  };
}

let thisss = new Person('thatbetty', 'thatzhao');

let thatt = {firstname: 'thisbetty', lastname: 'thiszhao'};

Thisss.sayHi.call (thatt);

 -1
Author: ht zhao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-02 05:16:06