Jak działa słowo kluczowe "this"?

Zauważyłem, że nie wydaje się być jasne wyjaśnienie, czym jest słowo kluczowe this i jak jest poprawnie (i nieprawidłowo) używane w JavaScript na stronie przepełnienie stosu.

Byłem świadkiem pewnego bardzo dziwnego zachowania z nim i nie udało mi się zrozumieć, dlaczego to się stało.

Jak działa this i kiedy należy go stosować?

Author: JJJ, 2010-06-27

20 answers

Polecam przeczytać Mike West ' s article Scope in JavaScript (mirror) najpierw. Jest to doskonałe, przyjazne wprowadzenie do koncepcji this i łańcuchów zakresu w JavaScript.

Kiedy zaczniesz się przyzwyczajać this, zasady są całkiem proste. Standard ECMAScript 5.1 definiuje this:

§11.1.1 słowo kluczowe this

Słowo kluczowe this ocenia na wartość ThisBinding of the current execution context

ThisBinding jest czymś, co interpreter JavaScript utrzymuje podczas ewaluacji kodu JavaScript, jak specjalny rejestr PROCESORA, który zawiera odniesienie do obiektu. Interpreter aktualizuje to powiązanie, gdy tylko tworzy kontekst wykonania w jednym z trzech różnych przypadków:

1. Initial global execution context

Tak jest w przypadku kodu JavaScript, który jest oceniany na najwyższym poziomie, np. gdy bezpośrednio wewnątrz <script>:

<script>
  alert("I'm evaluated in the initial global execution context!");

  setTimeout(function () {
      alert("I'm NOT evaluated in the initial global execution context.");
  }, 1);
</script>

Podczas oceniania kodu w początkowym globalnym kontekście wykonywania, ThisBinding jest ustawiany na global object, window (§10.4.1.1).

Wprowadzanie kodu eval

  • ...poprzez bezpośrednie wywołanie do eval() To powiązanie pozostaje bez zmian; jest to ta sama wartość co to powiązanie kontekstu wywołującego wykonanie (§10.4.2 (2)(a)).

  • ...jeśli nie przez bezpośrednie połączenie do eval()
    To ustawienie jest ustawione na obiekt globalny tak, jakby był wykonywany w początkowym globalnym kontekście wykonania (§10.4.2 (1)).

§15.1.2.1.1 określa czym jest bezpośrednie wywołanie do eval(). Zasadniczo, eval(...) jest bezpośrednim wywołaniem, podczas gdy coś w rodzaju (0, eval)(...) lub var indirectEval = eval; indirectEval(...); jest pośrednim wywołaniem do eval(). Zobacz odpowiedź Chucka na (1, eval) ('this') vs eval ('this') W JavaScript? i ECMA-262-5 Dmitrija Sosnikowa w szczegółach. Rozdział 2. Tryb Ścisły. for when you might użyj pośredniego wywołania eval().

Wprowadzanie kodu funkcji

Występuje to podczas wywoływania funkcji. Jeśli na obiekcie zostanie wywołana funkcja, np. w obj.myMethod() lub równoważnym obj["myMethod"](), to w przykładzie zostanie ustawiona wartość thisbinding na object (obj ; §13.2.1). W większości innych przypadków ThisBinding jest ustawiony na obiekt globalny (§10.4.3).

Powodem napisania "w większości innych przypadków" jest to, że istnieje osiem wbudowanych funkcji ECMAScript 5, które pozwalają To ustawienie ma być określone na liście argumentów. Te specjalne funkcje przyjmują tzw. thisArg, która staje się Thisbindingiem podczas wywoływania funkcji (§10.4.3).

Te specjalne wbudowane funkcje to:

  • Function.prototype.apply( thisArg, argArray )
  • Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
  • Array.prototype.every( callbackfn [ , thisArg ] )
  • Array.prototype.some( callbackfn [ , thisArg ] )
  • Array.prototype.forEach( callbackfn [ , thisArg ] )
  • Array.prototype.map( callbackfn [ , thisArg ] )
  • Array.prototype.filter( callbackfn [ , thisArg ] )

W przypadku funkcji Function.prototype są one wywoływane na funkcji obiekt, ale zamiast ustawiać to powiązanie na obiekt funkcyjny, to ustawienie jest ustawione na thisArg.

W przypadku funkcji Array.prototype, podany {[38] } jest wywoływany w kontekście wykonywania, w którym ThisBinding jest ustawiony na thisArg, jeśli jest podany; w przeciwnym wypadku obiekt globalny.

To są zasady dla zwykłego JavaScript. JQuery), może się okazać, że niektóre funkcje biblioteczne manipulują wartością this. Twórcy tych Biblioteki JavaScript robią to, ponieważ zwykle obsługują najczęstsze przypadki użycia, a użytkownicy biblioteki zazwyczaj uważają to zachowanie za wygodniejsze. Przekazując funkcje wywołania zwrotnego odwołujące się do this do funkcji bibliotecznych, należy zapoznać się z dokumentacją w celu uzyskania gwarancji, jaka jest wartość this podczas wywoływania funkcji.

Jeśli zastanawiasz się, jak biblioteka JavaScript manipuluje wartością this, Biblioteka jest po prostu za pomocą jednego z wbudowanych Funkcje JavaScript akceptujące thisArg. Ty też możesz napisać własną funkcję przy użyciu funkcji zwrotnej i thisArg:

function doWork(callbackfn, thisArg) {
    //...
    if (callbackfn != null) callbackfn.call(thisArg);
}
Jest specjalna sprawa, o której jeszcze nie wspomniałem. Podczas konstruowania nowego obiektu za pomocą operatora new, interpreter JavaScript tworzy nowy, pusty obiekt, ustawia pewne wewnętrzne właściwości, a następnie wywołuje funkcję konstruktora na nowym obiekcie. Tak więc, gdy funkcja jest wywoływana w kontekście konstruktora, wartość this jest nowym obiektem, który interpreter utworzony:
function MyType() {
    this.someData = "a string";
}

var instance = new MyType();
// Kind of like the following, but there are more steps involved:
// var instance = {};
// MyType.call(instance);

Dla Zabawy, przetestuj swoje zrozumienie na kilku przykładach

aby odsłonić odpowiedzi, najedź kursorem na jasnożółte pola.

  1. Jaka jest wartość this w zaznaczonej linii? Dlaczego?

    window - zaznaczona linia jest oceniana w początkowym globalnym kontekście wykonania.

    if (true) {
        // What is `this` here?
    }
    
  2. Jaka jest wartość this w zaznaczonej linii podczas wykonywania obj.staticFunction()? Dlaczego?

    obj - podczas wywoływania funkcji na obiekcie, Tobinding jest ustawiany na obiekt.

    var obj = {
        someData: "a string"
    };
    
    function myFun() {
        return this // What is `this` here?
    }
    
    obj.staticFunction = myFun;
    
    console.log("this is window:", obj.staticFunction() == window);
    console.log("this is obj:", obj.staticFunction() == obj);
      
  3. Jaka jest wartość this w zaznaczonej linii? Dlaczego?

    window

    W tym przykładzie interpreter JavaScript wprowadza kod funkcji, ale ponieważ myFun/obj.myMethod nie jest wywoływane na obiekcie, ThisBinding jest ustawione na window.

    Różni się to od Pythona, w którym dostęp do metody (obj.myMethod) tworzy obiekt metody wiązanej .

    var obj = {
        myMethod: function () {
            return this; // What is `this` here?
        }
    };
    var myFun = obj.myMethod;
    console.log("this is window:", myFun() == window);
    console.log("this is obj:", myFun() == obj);
      
  4. Jaka jest wartość this w zaznaczonej linii? Dlaczego?

    window

    To było trudne. Przy ocenie kodu eval, this jest obj. Jednak w kodzie eval, {[55] } nie jest wywoływany na obiekcie, więc dla wywołania jest ustawione na window.
    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        myMethod: function () {
            eval("myFun()");
        }
    };
    
  5. Jaka jest wartość this w zaznaczonej linii? Dlaczego?

    obj

    Linia myFun.call(obj); wywołuje specjalną wbudowaną funkcję Function.prototype.call(), która przyjmuje thisArg jako pierwszy argument.

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        someData: "a string"
    };
    console.log("this is window:", myFun.call(obj) == window);
    console.log("this is obj:", myFun.call(obj) == obj);
      
 1176
Author: Daniel Trebbien,
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-05-27 03:41:28

Słowo kluczowe this zachowuje się w JavaScript inaczej niż w innym języku. W językach obiektowych słowo kluczowe this odnosi się do bieżącej instancji klasy. W JavaScript wartość this jest określana głównie przez kontekst wywołania funkcji (context.function()) i gdzie się nazywa.

1. W przypadku użycia w kontekście globalnym

Kiedy używasz this W kontekście globalnym, jest on związany z obiektem globalnym (window w przeglądarka)

document.write(this);  //[object Window]

Kiedy używasz this wewnątrz funkcji zdefiniowanej w kontekście globalnym, {[12] } jest nadal związana z obiektem globalnym, ponieważ funkcja jest faktycznie metodą globalnego kontekstu.

function f1()
{
   return this;
}
document.write(f1());  //[object Window]

Powyżej {[20] } jest wykonana metoda obiektu globalnego. W ten sposób możemy również wywołać obiekt window w następujący sposób:

function f()
{
    return this;
}

document.write(window.f()); //[object Window]

2. W przypadku użycia wewnątrz obiektu metoda

Kiedy używasz słowa kluczowego this wewnątrz metody obiektowej, this jest związane z "immediate" / align = "left" /

var obj = {
    name: "obj",
    f: function () {
        return this + ":" + this.name;
    }
};
document.write(obj.f());  //[object Object]:obj

Powyżej umieściłem słowo natychmiastowe w podwójnych cudzysłowach. Chodzi o to, że jeśli zagnieżdżasz obiekt wewnątrz innego obiektu, to this jest powiązany z bezpośrednim rodzicem.

var obj = {
    name: "obj1",
    nestedobj: {
        name:"nestedobj",
        f: function () {
            return this + ":" + this.name;
        }
    }            
}

document.write(obj.nestedobj.f()); //[object Object]:nestedobj

Nawet jeśli dodasz funkcję jawnie do obiektu jako metodę, to nadal postępuje ona zgodnie z powyższymi regułami, tzn. this nadal wskazuje na bezpośredni obiekt nadrzędny.

var obj1 = {
    name: "obj1",
}

function returnName() {
    return this + ":" + this.name;
}

obj1.f = returnName; //add method to object
document.write(obj1.f()); //[object Object]:obj1

3. Podczas wywoływania funkcji bez kontekstu

Kiedy używasz this wewnątrz funkcja, która jest wywoływana bez żadnego kontekstu (tzn. nie na żadnym obiekcie), jest powiązana z obiektem globalnym (window w przeglądarce) (nawet jeśli funkcja jest zdefiniowana wewnątrz obiektu).

var context = "global";

var obj = {  
    context: "object",
    method: function () {                  
        function f() {
            var context = "function";
            return this + ":" +this.context; 
        };
        return f(); //invoked without context
    }
};

document.write(obj.method()); //[object Window]:global 

Wypróbuj to wszystko za pomocą funkcji

Możemy wypróbować powyższe punkty za pomocą funkcji. Istnieją jednak pewne różnice.

  • powyżej dodaliśmy elementy do obiektów używając dosłownej notacji obiektu. Możemy dodawać członków do funkcji za pomocą this. aby określić oni.
  • literalna notacja obiektu tworzy instancję obiektu, której możemy natychmiast użyć. W przypadku funkcji możemy najpierw utworzyć jej instancję używając operatora new.
  • również w dosłownym podejściu obiektowym, możemy jawnie dodawać elementy składowe do już zdefiniowanego obiektu za pomocą operatora kropki. Jest to dodawane tylko do konkretnej instancji. Jednak dodałem zmienną do prototypu funkcji tak, że dostaje odzwierciedlenie we wszystkich instancjach funkcji.

Poniżej Wypróbowałem wszystkie rzeczy, które zrobiliśmy z obiektem i this powyżej, ale najpierw tworząc funkcję, a nie bezpośrednio pisząc obiekt.

/********************************************************************* 
  1. When you add variable to the function using this keyword, it 
     gets added to the function prototype, thus allowing all function 
     instances to have their own copy of the variables added.
*********************************************************************/
function functionDef()
{
    this.name = "ObjDefinition";
    this.getName = function(){                
        return this+":"+this.name;
    }
}        

obj1 = new functionDef();
document.write(obj1.getName() + "<br />"); //[object Object]:ObjDefinition   

/********************************************************************* 
   2. Members explicitly added to the function protorype also behave 
      as above: all function instances have their own copy of the 
      variable added.
*********************************************************************/
functionDef.prototype.version = 1;
functionDef.prototype.getVersion = function(){
    return "v"+this.version; //see how this.version refers to the
                             //version variable added through 
                             //prototype
}
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   3. Illustrating that the function variables added by both above 
      ways have their own copies across function instances
*********************************************************************/
functionDef.prototype.incrementVersion = function(){
    this.version = this.version + 1;
}
var obj2 = new functionDef();
document.write(obj2.getVersion() + "<br />"); //v1

obj2.incrementVersion();      //incrementing version in obj2
                              //does not affect obj1 version

document.write(obj2.getVersion() + "<br />"); //v2
document.write(obj1.getVersion() + "<br />"); //v1

/********************************************************************* 
   4. `this` keyword refers to the immediate parent object. If you 
       nest the object through function prototype, then `this` inside 
       object refers to the nested object not the function instance
*********************************************************************/
functionDef.prototype.nestedObj = { name: 'nestedObj', 
                                    getName1 : function(){
                                        return this+":"+this.name;
                                    }                            
                                  };

document.write(obj2.nestedObj.getName1() + "<br />"); //[object Object]:nestedObj

/********************************************************************* 
   5. If the method is on an object's prototype chain, `this` refers 
      to the object the method was called on, as if the method was on 
      the object.
*********************************************************************/
var ProtoObj = { fun: function () { return this.a } };
var obj3 = Object.create(ProtoObj); //creating an object setting ProtoObj
                                    //as its prototype
obj3.a = 999;                       //adding instance member to obj3
document.write(obj3.fun()+"<br />");//999
                                    //calling obj3.fun() makes 
                                    //ProtoObj.fun() to access obj3.a as 
                                    //if fun() is defined on obj3

4. W przypadku użycia wewnątrz funkcji konstruktora .

Gdy funkcja jest używana jako konstruktor (tzn. gdy jest wywoływana za pomocą słowa kluczowego new), this wewnątrz ciała funkcji wskazuje na nowy konstruowany obiekt.

var myname = "global context";
function SimpleFun()
{
    this.myname = "simple function";
}

var obj1 = new SimpleFun(); //adds myname to obj1
//1. `new` causes `this` inside the SimpleFun() to point to the
//   object being constructed thus adding any member
//   created inside SimipleFun() using this.membername to the
//   object being constructed
//2. And by default `new` makes function to return newly 
//   constructed object if no explicit return value is specified

document.write(obj1.myname); //simple function

5. W przypadku użycia wewnątrz funkcji zdefiniowanej na łańcuchu prototypów

Jeśli metoda znajduje się w łańcuchu prototypów obiektu, this wewnątrz takiej metody odnosi się do obiektu, na którym została wywołana metoda, tak jakby metoda została zdefiniowana na obiekcie.

var ProtoObj = {
    fun: function () {
        return this.a;
    }
};
//Object.create() creates object with ProtoObj as its
//prototype and assigns it to obj3, thus making fun() 
//to be the method on its prototype chain

var obj3 = Object.create(ProtoObj);
obj3.a = 999;
document.write(obj3.fun()); //999

//Notice that fun() is defined on obj3's prototype but 
//`this.a` inside fun() retrieves obj3.a   

6. Wewnątrz funkcji call (), apply () i bind ()

  • wszystkie te metody są zdefiniowane na Function.prototype.
  • te metody pozwalają na napisanie funkcji raz i wywołanie jej w innym kontekście. Innymi słowy, pozwalają określić wartość this, która będzie używana, gdy funkcja jest egzekucja. Pobierają również wszelkie parametry, które mają być przekazywane do oryginalnej funkcji podczas jej wywoływania.
  • fun.apply(obj1 [, argsArray]) Ustawia obj1 jako wartość this wewnątrz fun() i wywołuje fun() przekazując elementy argsArray jako swoje argumenty.
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Ustawia obj1 jako wartość this wewnątrz fun() i wywołuje fun() przekazując arg1, arg2, arg3, ... jako swoje argumenty.
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]]) - Zwraca odwołanie do funkcji fun Z this wewnątrz obj1 i parametry fun związane z parametrami podanymi arg1, arg2, arg3,....
  • do tej pory różnica między apply, call i bind musiało stać się oczywiste. apply pozwala określić argumenty, które będą funkcjonować jako obiekt typu array, tzn. obiekt z właściwością numeryczną length i odpowiadającymi jej nieujemnymi właściwościami całkowitymi. Natomiast call pozwala na bezpośrednie podanie argumentów funkcji. Zarówno apply, jak i call natychmiast wywołują funkcję w określonym kontekście i z podanymi argumentami. Z drugiej strony, bind po prostu zwraca funkcję związaną z podaną wartością this i argumentami. Możemy uchwycić odniesienie do tej zwracanej funkcji, przypisując ją do zmiennej, a później możemy ją wywołać w dowolnym momencie.
function add(inc1, inc2)
{
    return this.a + inc1 + inc2;
}

var o = { a : 4 };
document.write(add.call(o, 5, 6)+"<br />"); //15
      //above add.call(o,5,6) sets `this` inside
      //add() to `o` and calls add() resulting:
      // this.a + inc1 + inc2 = 
      // `o.a` i.e. 4 + 5 + 6 = 15
document.write(add.apply(o, [5, 6]) + "<br />"); //15
      // `o.a` i.e. 4 + 5 + 6 = 15

var g = add.bind(o, 5, 6);       //g: `o.a` i.e. 4 + 5 + 6
document.write(g()+"<br />");    //15

var h = add.bind(o, 5);          //h: `o.a` i.e. 4 + 5 + ?
document.write(h(6) + "<br />"); //15
      // 4 + 5 + 6 = 15
document.write(h() + "<br />");  //NaN
      //no parameter is passed to h()
      //thus inc2 inside add() is `undefined`
      //4 + 5 + undefined = NaN</code>

7. this wewnątrz procedury obsługi zdarzeń

  • gdy przypisujesz funkcję bezpośrednio do procesów obsługi zdarzeń elementu, użycie {[12] } bezpośrednio wewnątrz funkcji obsługi zdarzeń odnosi się do odpowiedni element. Takie bezpośrednie przypisanie funkcji może być wykonane metodą addeventListener lub tradycyjnymi metodami rejestracji zdarzeń, takimi jak onclick.
  • podobnie, gdy używasz this bezpośrednio wewnątrz właściwości event (jak <button onclick="...this..." >) elementu, odnosi się on do elementu.
  • jednakże użycie this pośrednio przez inną funkcję wywołaną wewnątrz funkcji obsługi zdarzeń lub właściwości zdarzenia rozwiązuje obiekt globalny window.
  • to samo powyżej zachowanie jest osiągane, gdy dołączamy funkcję do obsługi zdarzeń za pomocą metody Microsoft Event Registration model attachEvent. Zamiast przypisywać funkcję do obsługi zdarzenia (i w ten sposób tworzyć metodę funkcji elementu), wywołuje funkcję w zdarzeniu (skutecznie wywołując ją w kontekście globalnym).

polecam lepiej wypróbować to w JSFiddle.

<script> 
    function clickedMe() {
       alert(this + " : " + this.tagName + " : " + this.id);
    } 
    document.getElementById("button1").addEventListener("click", clickedMe, false);
    document.getElementById("button2").onclick = clickedMe;
    document.getElementById("button5").attachEvent('onclick', clickedMe);   
</script>

<h3>Using `this` "directly" inside event handler or event property</h3>
<button id="button1">click() "assigned" using addEventListner() </button><br />
<button id="button2">click() "assigned" using click() </button><br />
<button id="button3" onclick="alert(this+ ' : ' + this.tagName + ' : ' + this.id);">used `this` directly in click event property</button>

<h3>Using `this` "indirectly" inside event handler or event property</h3>
<button onclick="alert((function(){return this + ' : ' + this.tagName + ' : ' + this.id;})());">`this` used indirectly, inside function <br /> defined & called inside event property</button><br />

<button id="button4" onclick="clickedMe()">`this` used indirectly, inside function <br /> called inside event property</button> <br />

IE only: <button id="button5">click() "attached" using attachEvent() </button>
 127
Author: Mahesha999,
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-05-07 13:42:03

Javascript ' s this

Wywołanie prostej funkcji

Rozważmy następującą funkcję:

function foo() {
    console.log("bar");
    console.log(this);
}
foo(); // calling the function

Zauważ, że uruchamiamy to w trybie normalnym, tzn. tryb ścisły nie jest używany.

Po uruchomieniu w przeglądarce, wartość this zostanie zalogowana jako window. Dzieje się tak dlatego, że window jest zmienną globalną w zakresie przeglądarki internetowej.

Jeśli uruchomisz ten sam fragment kodu w środowisku takim jak node.js, this odnosi się do globalnego zmienna w aplikacji.

Teraz, jeśli uruchomimy to w trybie ścisłym, dodając polecenie "use strict"; na początku deklaracji funkcji, this nie będzie już odwoływać się do zmiennej globalnej w żadnym z envirnomentów. Odbywa się to w celu uniknięcia nieporozumień w trybie ścisłym. this czy, w tym przypadku po prostu log undefined, ponieważ to jest to, co jest, nie jest zdefiniowane.

W następujących przypadkach zobaczymy, jak manipulować wartością this.

Wywołanie funkcji na obiekcie

Są różne sposoby, aby to zrobić. Jeśli wywołałeś natywne metody w Javascript, takie jak forEach i slice, powinieneś już wiedzieć, że zmienna this w tym przypadku odnosi się do Object, na której wywołałeś tę funkcję (zauważ, że w javascript prawie wszystko jest Object, w tym Arrays I Functions). Weźmy na przykład następujący kod.

var myObj = {key: "Obj"};
myObj.logThis = function () {
    // I am a method
    console.log(this);
}
myObj.logThis(); // myObj is logged

Jeśli Object zawiera właściwość, która zawiera Function, właściwość nazywa się metodą. To metoda, gdy zostanie wywołana, zawsze będzie miała zmienną this ustawioną na Object, z którą jest skojarzona. Dotyczy to zarówno trybów strict, jak i non-strict.

Zauważ, że jeśli metoda jest przechowywana (a raczej kopiowana) w innej zmiennej, odniesienie do this nie jest już zachowywane w nowej zmiennej. Na przykład:

// continuing with the previous code snippet

var myVar = myObj.thisMethod;
myVar();
// logs either of window/global/undefined based on mode of operation

Rozważając bardziej praktyczny scenariusz:

var el = document.getElementById('idOfEl');
el.addEventListener('click', function() { console.log(this) });
// the function called by addEventListener contains this as the reference to the element
// so clicking on our element would log that element itself

Słowo kluczowe new

Rozważmy funkcję konstruktora w Javascript:

function Person (name) {
    this.name = name;
    this.sayHello = function () {
        console.log ("Hello", this);
    }
}

var awal = new Person("Awal");
awal.sayHello();
// In `awal.sayHello`, `this` contains the reference to the variable `awal`
Jak to działa? Zobaczmy, co się stanie, gdy użyjemy słowa kluczowego new.
  1. wywołanie funkcji ze słowem kluczowym new spowoduje natychmiastowe zainicjowanie Object typu Person.
  2. konstruktor tego Object ma swój konstruktor ustawiony na Person. Zauważ również, że typeof awal zwróci tylko Object.
  3. ten nowy Object zostanie przypisany prototype Person.prototype. Oznacza to, że każda metoda lub właściwość w Person prototyp będzie dostępny dla wszystkich instancji Person, W tym awal.
  4. sama funkcja Person jest teraz wywoływana; this jest odniesieniem do nowo zbudowanego obiektu awal.

Całkiem prosto, co?

Zauważ, że oficjalny ECMAScript spec no gdzie stwierdza, że tego typu funkcje są rzeczywistymi funkcjami constructor. Są to po prostu normalne funkcje i new mogą być używane na dowolnej funkcji. Chodzi o to, że używamy ich jako takich, a więc nazywamy tylko oni jako tacy.

Wywołanie funkcji na funkcjach: call i apply

Więc tak, ponieważ function S są również Objects (a w rzeczywistości zmienne pierwszej klasy w Javascript), nawet funkcje mają metody, które są... same funkcje.

Wszystkie funkcje dziedziczą z globalnej Function, a dwie z jej wielu metod to call i apply, i obie mogą być użyte do manipulowania wartością this w funkcji, na której są wywoływane.

function foo () { console.log (this, arguments); }
var thisArg = {myObj: "is cool"};
foo.call(thisArg, 1, 2, 3);

To jest typowy przykład użycia call. Zasadniczo przyjmuje pierwszy parametr i ustawia this w funkcji foo jako odniesienie do thisArg. Wszystkie pozostałe parametry przekazywane do {[50] } są przekazywane do funkcji foo jako argumenty.
Tak więc powyższy kod loguje {myObj: "is cool"}, [1, 2, 3] w konsoli. Całkiem niezły sposób na zmianę wartości this W dowolnej funkcji.

apply jest prawie takie samo jak call przyjąć, że przyjmuje tylko dwa parametry: thisArg i tablicę zawierającą argumenty do przekazania do funkcji. Tak więc powyższe wywołanie {[50] } można przetłumaczyć na apply w następujący sposób:

foo.apply(thisArg, [1,2,3])

Zauważ, że call i apply mogą nadpisać wartość this ustawioną za pomocą metody dot, o której mówiliśmy w drugim pocisku. Proste:)

Prezentuję.... bind!

bind jest bratem call i apply. Jest to również metoda dziedziczona przez wszystkie funkcje z globalnego konstruktora Function w Javascript. Różnica między bind a call/apply czy to i to call i apply faktycznie wywołają funkcję. bind, Z drugiej strony, zwraca nową funkcję z wstępnie ustawionymi thisArg i arguments. Weźmy przykład, aby lepiej to zrozumieć: {]}

function foo (a, b) {
    console.log (this, arguments);
}
var thisArg = {myObj: "even more cool now"};
var bound = foo.bind(thisArg, 1, 2);
console.log (typeof bound); // logs `function`
console.log (bound);
/* logs `function () { native code }` */

bound(); // calling the function returned by `.bind`
// logs `{myObj: "even more cool now"}, [1, 2]`
Widzisz różnicę między tymi trzema? Są subtelne, ale są używane inaczej. Jak call iapply, bind spowoduje również przekroczenie wartości this ustawionej przez wywołanie metody kropkowej.

Zauważ również, że żadna z tych trzech funkcji nie zmienia pierwotnej funkcji. call i apply zwrócą wartość ze świeżo skonstruowanych funkcji, podczas gdy bind zwróci świeżo skonstruowaną funkcję, gotową do wywołania.

Extra stuff, copy this

Czasami nie podoba Ci się fakt, że this zmienia się z scope, specjalnie zagnieżdżonym scope. Spójrz na poniższy przykład.

var myObj = {
    hello: function () {
        return "world"
        },
    myMethod: function () {
        // copy this, variable names are case-sensitive
        var that = this;
        // callbacks ftw \o/
        foo.bar("args", function () {
            // I want to call `hello` here
            this.hello(); // error
            // but `this` references to `foo` damn!
            // oh wait we have a backup \o/
            that.hello(); // "world"
        });
    }
  };

W powyższym kodzie widzimy, że wartość this zmieniła się z zagnieżdżonym zakresem, ale chcieliśmy wartość this od oryginału zakres. Więc "skopiowaliśmy" this do that i użyliśmy kopii zamiast this. Sprytne, co?

Indeks:

  1. co jest domyślnie przechowywane w this?
  2. co jeśli wywołamy funkcję jako metodę z notacją obiektowo-kropkową?
  3. co jeśli użyjemy słowa kluczowego new?
  4. jak manipulować this za pomocą call i apply?
  5. za pomocą bind.
  6. kopiowanie this w celu rozwiązania problemów z zagnieżdżonym zakresem.
 49
Author: Awal Garg,
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-10-27 09:40:54

" tu " chodzi o zakres. Każda funkcja ma swój własny zakres, a ponieważ wszystko w JS jest obiektem, nawet funkcja może przechowywać pewne wartości w sobie za pomocą "this". OOP 101 uczy, że "to" ma zastosowanie tylko do instancji obiektu. Dlatego za każdym razem, gdy funkcja wykonuje, nowa "instancja" tej funkcji ma nowe znaczenie "to".

Większość ludzi się myli, gdy próbują użyć" tego " wewnątrz anonimowych funkcji zamknięcia, takich jak:]}

(function(value) {
    this.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = this.value;        // uh oh!! possibly undefined
    });
})(2);

Więc tutaj, wewnątrz each (), "this" nie zawiera "wartości", której oczekujesz (od

this.value = value;
nad nim). Tak więc, aby przejść przez ten (nie zamierzony kalambur) problem, deweloper może:
(function(value) {
    var self = this;            // small change
    self.value = value;
    $('.some-elements').each(function(elt){
        elt.innerHTML = self.value;        // phew!! == 2 
    });
})(2);

Wypróbuj to; zaczniesz lubić ten wzór programowania

 44
Author: arunjitsingh,
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-10-29 05:00:41

this w Javascript zawsze odnosi się do 'właściciela' funkcji, która jest wykonywana.

Jeśli nie zdefiniowano jawnego właściciela, to odwołuje się do najwyższego właściciela most, obiektu window.

So if I did

function someKindOfFunction() {
   this.style = 'foo';
}

element.onclick = someKindOfFunction;

this odnosi się do obiektu elementu. Ale uważaj, wiele osób popełnia ten błąd

<element onclick="someKindOfFunction()">

W tym drugim przypadku wystarczy odwołać się do funkcji, a nie przekazać ją elementowi. this będzie odnosi się do obiektu window.

 14
Author: Seph,
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
2013-10-06 19:46:35

ponieważ ten wątek się rozwinął, zebrałem kilka punktów dla czytelników nowych w temacie this.

Jak określa się wartość this?

Używamy tego podobnie do sposobu, w jaki używamy zaimków w językach naturalnych, takich jak angielski: "John działa szybko, ponieważ on próbuje złapać pociąg."Zamiast tego moglibyśmy napisać "... John próbuje złapać pociąg".

var person = {    
    firstName: "Penelope",
    lastName: "Barrymore",
    fullName: function () {

    // We use "this" just as in the sentence above:
       console.log(this.firstName + " " + this.lastName);

    // We could have also written:
       console.log(person.firstName + " " + person.lastName);
    }
}

this nie jest przypisany a wartość dopóki obiekt nie wywoła funkcji, w której jest zdefiniowana. W globalnym zasięgu wszystkie globalne zmienne i funkcje są zdefiniowane na obiekcie window. Dlatego this w funkcji globalnej odnosi się do (i ma wartość) obiektu global window.

Kiedy use strict, this w funkcjach globalnych i anonimowych, które nie są związane z żadnym obiektem posiada wartość undefined.

Słowo kluczowe this jest najbardziej niezrozumiałe gdy: 1) pożyczamy metodę, która używa this, 2) przypisanie metody, która używa this do zmiennej, 3) funkcja, która używa {[2] } jest przekazywana jako funkcja zwrotna, a 4) this jest używana wewnątrz funkcji zamkniętej - wewnętrznej. (2)

tabela

Co kryje przyszłość

Zdefiniowany w skrypcie ECMA 6 , funkcje strzałkowe przyjmują Wiązanie this z enclosing (function or global) scope.

function foo() {
     // return an arrow function
     return (a) => {
     // `this` here is lexically inherited from `foo()`
     console.log(this.a);
  };
}
var obj1 = { a: 2 };
var obj2 = { a: 3 };

var bar = foo.call(obj1);
bar.call( obj2 ); // 2, not 3!

Podczas gdy funkcje strzałek stanowią alternatywę dla użycia bind(), Ważne jest, aby pamiętać, że zasadniczo wyłączenie tradycyjnego mechanizmu this na rzecz szerzej rozumianego zakresu leksykalnego. (1)


linki:

  1. this & Object prototypy, Kyle Simpson. © 2014 Getify Solutions.
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. Angus Croll - http://goo.gl/Z2RacU
 14
Author: carlodurso,
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-10-30 03:58:06

Każda Funkcja kontekst wykonania w javascript ma zakres kontekst parametr ustawiony przez:

  1. Jak funkcja jest wywoływana (w tym jako metoda obiektowa, użycie call i apply , użycie new )
  2. użycie bind
  3. leksykalnie dla funkcji strzałek (przyjmują to ich zewnętrznego kontekstu wykonania)

niezależnie od kontekstu tego zakresu, jest / align = "left" /

Możesz zmienić to ustawić wartość to Zakres context using func.call, func.apply lub func.bind.

Domyślnie, a co myli większość początkujących, gdy wywołanie zwrotne jest wywoływane po wywołaniu zdarzenia na elemencie DOM, kontekst zakresu Ta wartość funkcji jest elementem DOM.

JQuery sprawia, że to banalne, aby zmienić z jQuery.proxy.

 11
Author: blockhead,
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
2017-04-26 03:54:14

Tutaj jest jednym z dobrych źródeł this W JavaScript.

Oto podsumowanie:

  • Global this

    W przeglądarce, w zasięgu globalnym, this jest obiektem window

    <script type="text/javascript">
      console.log(this === window); // true
      var foo = "bar";
      console.log(this.foo); // "bar"
      console.log(window.foo); // "bar"
    

    W node używając repl, this jest górną przestrzenią nazw. Można go nazwać global.

    >this
      { ArrayBuffer: [Function: ArrayBuffer],
        Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
        Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
        ...
    >global === this
     true
    

    In node executing from a script, this at the global scope starts as a empty object. To nie to samo co global

    \\test.js
    console.log(this);  \\ {}
    console.log(this === global); \\ fasle
    
  • Function this

Z wyjątkiem przypadków obsługi zdarzeń DOM lub gdy thisArg jest dostarczany (patrz dalej w dół), zarówno w węźle, jak i w przeglądarce używając this w funkcji, która nie jest wywoływana z new odwołuje się do globalnego zakresu ...

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();
    console.log(this.foo); //logs "foo"
</script>

Jeśli użyjesz use strict;, W takim przypadku this będzie undefined

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      "use strict";
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    testThis();  //Uncaught TypeError: Cannot set property 'foo' of undefined 
</script>

Jeśli wywołasz funkcję z new this będzie nowym kontekstem, nie będzie odwoływać się do globalnego this.

<script type="text/javascript">
    foo = "bar";

    function testThis() {
      this.foo = "foo";
    }

    console.log(this.foo); //logs "bar"
    new testThis();
    console.log(this.foo); //logs "bar"

    console.log(new testThis().foo); //logs "foo"
</script>
  • prototype this

Tworzone funkcje stają się obiektami funkcyjnymi. Automatycznie otrzymują specjalną właściwość prototype, do której można przypisać wartości. Gdy tworzysz instancję wywołując funkcję za pomocą new, uzyskujesz dostęp do wartości przypisanych do właściwości prototype. Można uzyskać dostęp do tych wartości za pomocą this.

function Thing() {
  console.log(this.foo);
}

Thing.prototype.foo = "bar";

var thing = new Thing(); //logs "bar"
console.log(thing.foo);  //logs "bar"

Zwykle błędem jest przypisywanie tablic lub obiektów na prototype. Jeśli chcesz, aby instancje miały własne tablice, utwórz je w funkcji, a nie w prototypie.

function Thing() {
    this.things = [];
}

var thing1 = new Thing();
var thing2 = new Thing();
thing1.things.push("foo");
console.log(thing1.things); //logs ["foo"]
console.log(thing2.things); //logs []
  • obiekt ten

Możesz użyć this W dowolnej funkcji obiektu, aby odwołać się do innych właściwości tego obiektu. To nie to samo co instancja utworzona za pomocą new.

var obj = {
    foo: "bar",
    logFoo: function () {
        console.log(this.foo);
    }
};

obj.logFoo(); //logs "bar"
  • DOM event this

W HTML DOM event handler, this jest zawsze odniesieniem do elementu DOM, którego zdarzenie było dołączony do

function Listener() {
    document.getElementById("foo").addEventListener("click",
       this.handleClick);
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs "<div id="foo"></div>"
}

var listener = new Listener();
document.getElementById("foo").click();

Chyba że bind kontekst

function Listener() {
    document.getElementById("foo").addEventListener("click", 
        this.handleClick.bind(this));
}
Listener.prototype.handleClick = function (event) {
    console.log(this); //logs Listener {handleClick: function}
}

var listener = new Listener();
document.getElementById("foo").click();
  • HTML this

Wewnątrz atrybutów HTML, w których można umieścić JavaScript, this jest odniesieniem do elementu.

<div id="foo" onclick="console.log(this);"></div>
<script type="text/javascript">
document.getElementById("foo").click(); //logs <div id="foo"...
</script>
  • eval this

Możesz użyć eval, aby uzyskać dostęp this.

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    eval("console.log(this.foo)"); //logs "bar"
}

var thing = new Thing();
thing.logFoo();
  • z tym

Możesz użyć with, aby dodać this do bieżącego zakresu, aby odczytywać i zapisywać wartości na this bez wyraźnego odwoływania się do this.

function Thing () {
}
Thing.prototype.foo = "bar";
Thing.prototype.logFoo = function () {
    with (this) {
        console.log(foo);
        foo = "foo";
    }
}

var thing = new Thing();
thing.logFoo(); // logs "bar"
console.log(thing.foo); // logs "foo"
  • jQuery this

JQuery w wielu miejscach będzie miało this odniesienie do elementu DOM.

<div class="foo bar1"></div>
<div class="foo bar2"></div>
<script type="text/javascript">
$(".foo").each(function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").on("click", function () {
    console.log(this); //logs <div class="foo...
});
$(".foo").each(function () {
    this.click();
});
</script>
 9
Author: zangw,
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-03-25 14:23:39

Daniel, niesamowite Wyjaśnienie! Kilka słów na tej i dobrej liście wskaźnika kontekstu wykonania this W przypadku programów obsługi zdarzeń.

W dwóch słowach, this w JavaScript wskazuje obiekt, od którego (lub z którego kontekstu wykonania) została uruchomiona bieżąca funkcja i zawsze jest tylko do odczytu, i tak nie można jej ustawić (taka próba zakończy się Komunikatem 'Invalid left-side in assignment'.

Dla procesów obsługi zdarzeń: wbudowane procedury obsługi zdarzeń, takie jak <element onclick="foo">, zastąp wszelkie inne procedury obsługi dołączone wcześniej i wcześniej, więc bądź ostrożny i lepiej w ogóle nie wchodzić w delegację zdarzeń wbudowanych. I dzięki Zara Alaverdyan, która zainspirowała mnie do tej listy przykładów poprzez debatę niezgodną:)

  • el.onclick = foo; // in the foo - obj
  • el.onclick = function () {this.style.color = '#fff';} // obj
  • el.onclick = function() {doSomething();} // In the doSomething - Window
  • el.addEventListener('click',foo,false) // in the foo - obj
  • el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
  • <button onclick="this.style.color = '#fff';"> // obj
  • <button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">
 8
Author: Arman McHitarian,
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
2013-04-23 12:57:30

Istnieje wiele nieporozumień dotyczących tego, jak "to" jest interpretowane w JavaScript. Mam nadzieję, że ten artykuł położy wszystkich na spoczynek raz na zawsze. I wiele więcej. Przeczytaj uważnie cały artykuł. Uprzedzamy, że ten artykuł jest długi.

Niezależnie od kontekstu, w którym jest używany, "this" zawsze odwołuje się do "current object" W Javascript. Jednak czym jest "bieżący obiekt" różni się w zależności od kontekst . Kontekst może być dokładnie 1 z 6 następujący:

  1. Global (tzn. poza wszystkimi funkcjami)
  2. wewnątrz bezpośredniego wywołania funkcji niezwiązanej (tj. funkcji, która nie została związana przez wywołanie nazwa funkcji.bind)
  3. wewnątrz pośredniego wywołania funkcji niezwiązanej poprzez nazwa funkcji.call oraz nazwa funkcji.zastosuj
  4. wewnątrz wywołania "Bound Function" (tj. funkcji, która została związana przez wywołanie nazwa funkcji.bind)
  5. podczas tworzenia obiektu przez "Nowy"
  6. wewnątrz inline Dom event handler

Poniżej opisano każdy z tych kontekstów jeden po drugim:

  1. Kontekst Globalny (tj. poza wszystkimi funkcjami):

    Na Zewnątrz wszystkie funkcje (np. w kontekście globalnym) " current obiekt" (i stąd wartość "this" ) jest zawsze "okno" obiekt dla przeglądarek.

  2. Inside Direct" Non Bound Function " Call :

    Wewnątrz bezpośredniego wywołania funkcji niezwiązanej, obiekt, który wywołanie funkcji staje się "bieżącym obiektem" (i stąd wartość "this"). Jeśli funkcja jest wywoływana bez jawnego bieżącego obiekt , bieżący obiekt jest albo "window" object (dla trybu Non Strict) lub undefined (dla trybu Strict) . Dowolna funkcja (lub zmienna) zdefiniowana w globalny kontekst automatycznie staje się właściwością obiektu "window".Dla np. funkcja jest zdefiniowana w kontekście globalnym jako

    function UserDefinedFunction(){
        alert(this)
        }
    

    Staje się właściwością obiektu window, tak jakby zdefiniowano it as

    window.UserDefinedFunction=function(){
      alert(this)
    }  
    

    W Trybie "Non Strict", Wywołanie/Wywołanie ta funkcja bezpośrednio przez "UserDefinedFunction ()" automatycznie wywoła / wywoła to jako "okno.UserDefinedFunction () " making "window" as the "bieżący obiekt" (i stąd wartość "this") wewnątrz "UserDefinedFunction".Wywołanie tej funkcji w trybie "Non Strict Mode" spowoduje następujące

    UserDefinedFunction() // displays [object Window]  as it automatically gets invoked as window.UserDefinedFunction()
    

    W "trybie ścisłym" wywołanie / wywołanie funkcji bezpośrednio przez "UserDefinedFunction ()" will "Nie" automatycznie wywołaj / wywołaj okno ".UserDefinedFunction () " .Stąd " Prąd obiekt" (oraz wartość "this" ) wewnątrz "UserDefinedFunction" powinna być niezdefiniowana. Wywołanie tej funkcji w "trybie ścisłym" spowoduje następujące

    UserDefinedFunction() // displays undefined
    

    Jednak wywołanie go jawnie przy użyciu obiektu window spowoduje następujące

    window.UserDefinedFunction() // "always displays [object Window]   irrespective of mode."
    
    Spójrzmy na inny przykład. Proszę spojrzeć na następujące kod
     function UserDefinedFunction()
        {
            alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
        }
    
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
          }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    o1.f() // Shall display 1,2,undefined,undefined
    o2.f() // Shall display undefined,undefined,3,4
    

    W powyższym przykładzie widzimy, że gdy "UserDefinedFunction" było wywołane przez o1, "to" przyjmuje wartość o1 i wyświetlane są wartości jego właściwości "a" i "b". Wartość z " c " i "d" pokazano jako undefined as o1 robi nie definiuje tych właściwości

    Podobnie gdy "UserDefinedFunction" został wywołany przez o2 , "this" pobiera wartość o2 i wyświetla wartość jego właściwości "c" i "d".Wartość "a" i "b" pokazano jako undefined jako o2 nie definiuje tych właściwości.

  3. Wewnątrz pośredniego wywołania funkcji niezwiązanej poprzez nazwa funkcji.call oraz nazwa funkcji.zastosuj:

    Gdy a " nie związana Funkcja " jest wywoływana przez nazwa funkcji.call lub nazwa funkcji.zastosuj, "current object" (i stąd wartość "this" ) jest ustawiona na wartość "this" parametr (pierwszy parametr) przekazany do call / apply. Poniższy kod pokazuje to samo.

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
                a:1,
                b:2,
                f:UserDefinedFunction
           }
    var o2={
                c:3,
                d:4,
                f:UserDefinedFunction
           }
    
    UserDefinedFunction.call(o1) // Shall display 1,2,undefined,undefined
    UserDefinedFunction.apply(o1) // Shall display 1,2,undefined,undefined
    
    UserDefinedFunction.call(o2) // Shall display undefined,undefined,3,4
    UserDefinedFunction.apply(o2) // Shall display undefined,undefined,3,4
    
    o1.f.call(o2) // Shall display undefined,undefined,3,4
    o1.f.apply(o2) // Shall display undefined,undefined,3,4
    
    o2.f.call(o1) // Shall display 1,2,undefined,undefined
    o2.f.apply(o1) // Shall display 1,2,undefined,undefined
    

    Powyższy kod wyraźnie pokazuje, że "ta" wartość dla dowolnego " NON Funkcja Bound " może być zmieniona przez call/apply. Również, jeśli "this" parametr nie jest jawnie przekazywany do call/apply, "bieżący obiekt" (i stąd wartość "this") jest ustawiony na "window" W trybie niestrudzonym i "undefined" w trybie strict.

  4. Wewnątrz wywołania" Bound Function " (tj. funkcji, która została związana przez wywołanie nazwa funkcji.bind):

    Funkcja związana jest funkcją, której "ta" wartość została naprawione. Poniższy kod zademonstrował jak "this" Działa w przypadku of bound function

    function UserDefinedFunction()
    {
        alert(this.a + ","  + this.b + ","  + this.c  + ","  + this.d)
    }
    var o1={
              a:1,
              b:2,
              f:UserDefinedFunction,
              bf:null
           }
    var o2={
               c:3,
               d:4,
               f:UserDefinedFunction,
               bf:null
            }
    
    var bound1=UserDefinedFunction.bind(o1); // permanantly fixes "this" value of function "bound1" to Object o1
    bound1() // Shall display 1,2,undefined,undefined
    
    var bound2=UserDefinedFunction.bind(o2); // permanantly fixes "this" value of function "bound2" to Object o2
    bound2() // Shall display undefined,undefined,3,4
    
    var bound3=o1.f.bind(o2); // permanantly fixes "this" value of function "bound3" to Object o2
    bound3() // Shall display undefined,undefined,3,4
    
    var bound4=o2.f.bind(o1); // permanantly fixes "this" value of function "bound4" to Object o1
    bound4() // Shall display 1,2,undefined,undefined
    
    o1.bf=UserDefinedFunction.bind(o2) // permanantly fixes "this" value of function "o1.bf" to Object o2
    o1.bf() // Shall display undefined,undefined,3,4
    
    o2.bf=UserDefinedFunction.bind(o1) // permanantly fixes "this" value of function "o2.bf" to Object o1
    o2.bf() // Shall display 1,2,undefined,undefined
    
    bound1.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    
    bound1.apply(o2) // Shall still display 1,2,undefined,undefined. "apply" cannot alter the value of "this" for bound function
    
    o2.bf.call(o2) // Shall still display 1,2,undefined,undefined. "call" cannot alter the value of "this" for bound function
    o2.bf.apply(o2) // Shall still display 1,2,undefined,undefined."apply" cannot alter the value of "this" for bound function
    

    Jak podano w powyższym kodzie, "ta" wartość dla dowolnej " funkcji związanej" Nie można zmienić poprzez wywołanie / zastosowanie . Ponadto, jeśli "to" parametr nie jest jawnie przekazywany do bind, "bieżący obiekt" (i stąd wartość "this") jest ustawiona na "window" W Non tryb strict i "undefined" w trybie strict. Jeszcze jedno. Binding an funkcja already bound nie zmienia wartości "this". Pozostaje ustawiona jako wartość ustawiona przez pierwszą funkcję bind.

  5. Podczas tworzenia obiektów poprzez "nowe":

    Wewnątrz funkcji konstruktora, "bieżący obiekt" (i stąd wartość "this") odwołuje się do obiektu, który jest obecnie tworzony poprzez "new" niezależnie od statusu bind funkcji. Jednakże jeśli konstruktor jest funkcją związaną zostanie wezwany z predefiniowany zestaw argumentów ustawiony dla funkcji bound.

  6. Inline Dom event handler :

    Proszę spojrzeć na poniższy fragment HTML

    <button onclick='this.style.color=white'>Hello World</button>
    <div style='width:100px;height:100px;' onclick='OnDivClick(event,this)'>Hello World</div>
    

    "this" w powyższych przykładach odnoszą się do elementu "button" i element "div".

    W pierwszym przykładzie kolor czcionki przycisku należy ustawić na biały po kliknięciu.

    W drugim przykładzie gdy " div " element jest kliknięty powinien wywołanie funkcji OnDivClick z jej drugim parametrem odwoływanie się do klikniętego elementu div. Jednak wartość "tego" w OnDivClick nie może odwoływać się do klikniętego div element. Należy go ustawić jako "obiekt window" lub "undefined" w Non strict i Strict tryby odpowiednio (jeśli OnDivClick jest niezwiązaną funkcją ) lub ustawiony na predefiniowaną Bound value (if OnDivClick is a bound function )

Poniżej podsumowuje cały artykuł

  1. W kontekście globalnym "this" zawsze odnosi się do "window" obiektu

  2. Ilekroć funkcja jest wywoływana, jest wywoływana w kontekście obiekt ( "bieżący obiekt" ). Jeśli bieżący obiekt nie jest jawnie podany, bieżący obiekt to "okno obiekt " in NON Strict Mode i "undefined" domyślnie w trybie ścisłym.

  3. Wartość "this" w funkcji niezwiązanej jest odniesieniem do obiektu, w kontekście którego wywołana jest funkcja ( "bieżący obiekt")

  4. Wartość "this" w funkcji niezwiązanej może być nadpisana przez wywołaj i zastosuj metody funkcji.

  5. Wartość "to"{[11] } jest stałe dla funkcji wiązanej i nie może być overriden by call and apply methods of the function.

  6. Funkcja wiązania i już związana nie zmienia wartości "this". Pozostaje ustawiona jako wartość ustawiona przez pierwszą funkcję bind.

  7. Wartość "this" wewnątrz konstruktora jest obiektem, który jest tworzenie i inicjowanie

  8. Wartość "this" wewnątrz wiersza DOM obsługa zdarzeń jest referencją do elementu, dla którego podano obsługę zdarzenia.

 8
Author: Arup Hore,
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
2017-03-03 07:34:25

Prawdopodobnie najbardziej szczegółowy i wyczerpujący artykuł na temat this jest następujący:

Delikatne Wyjaśnienie słowa kluczowego' this ' W JavaScript

Ideą this jest zrozumienie, że typy wywoływania funkcji mają istotne znaczenie przy ustawianiu wartości this.


Gdy masz problemy z identyfikacją this, Nie zadaj sobie pytanie:

Gdzie jest this wzięte z ?

Ale czy zapytaj siebie:

Jak wywoływana jest funkcja ?

Dla funkcji strzałki (specjalny przypadek przezroczystości kontekstu) zadaj sobie pytanie:

Jaka wartość mA thisgdzie funkcja strzałki jest zdefiniowana?

Ten sposób myślenia jest prawidłowy przy radzeniu sobie z {[0] } i uchroni Cię przed bólem głowy.

 8
Author: Dmitri Pavlutin,
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-22 06:19:50

To najlepsze wytłumaczenie, jakie widziałem. zrozum JavaScripts to z jasnością

The this reference zawsze odnosi się do (i posiada wartość) an obiekt-pojedynczy obiekt-i jest zwykle używany wewnątrz funkcji lub metoda, chociaż może być używana poza funkcją w globalnym zakres. Zauważ, że gdy używamy trybu ścisłego, przechowuje on wartość undefined w funkcjach globalnych oraz w funkcjach anonimowych, które nie są związany z dowolnym obiekt.

Istnieją cztery warunki, w których to może być mylące:

  1. kiedy przekazujemy metodę (która wykorzystuje to ) jako parametr, który ma być użyty jako funkcja wywołania zwrotnego.
  2. innym przypadkiem, gdy jest to źle zrozumiane, jest użycie wewnętrznej metody (zamknięcia). Ważne jest, aby pamiętać, że zamknięcia nie mogą uzyskać dostępu do zewnętrznej zmiennej this za pomocą tego słowa kluczowego, ponieważ ta zmienna jest dostępna tylko przez funkcję siebie, a nie przez wewnętrzne funkcje.
  3. używając tego , gdy metoda jest przypisana do zmiennej. Wartość Ta jest powiązana z innym obiektem, jeśli przypisamy metodę, która tego używa do zmiennej
  4. używanie this Podczas używania metod bind, apply I call.

Podaje przykłady kodu, objaśnienia i poprawki kodu, które moim zdaniem były bardzo pomocne.

 6
Author: James Drinkard,
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-07-12 19:03:54

Trudno jest dobrze pojąć JS, lub napisać w nim coś bardziej trywialnego, jeśli nie rozumiesz tego dokładnie. Nie możesz sobie pozwolić na szybkie zanurzenie się:) myślę, że najlepszym sposobem na rozpoczęcie pracy z JS jest najpierw obejrzenie tych wykładów wideo Douglasa Crockforda - http://yuiblog.com/crockford / , który obejmuje to i tamto, i wszystko inne o JS.

 5
Author: tathagata,
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
2010-06-28 09:25:05

W kategoriach pseudoklasycznych, sposób w jaki wiele wykładów uczy słowa kluczowego 'this' jest obiektem utworzonym przez klasę lub konstruktor obiektu. Za każdym razem, gdy nowy obiekt jest konstruowany z klasy, wyobraź sobie, że pod maską jest tworzona i zwracana lokalna instancja 'tego' obiektu. Pamiętam, że tak to było:

function Car(make, model, year) {
var this = {}; // under the hood, so to speak
this.make = make;
this.model = model;
this.year = year;
return this; // under the hood
}

var mycar = new Car('Eagle', 'Talon TSi', 1993);
// ========= under the hood
var this = {};
this.make = 'Eagle';
this.model = 'Talon TSi';
this.year = 1993;
return this;
 5
Author: mrmaclean89,
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
2017-09-16 22:11:43

this jest jednym z niezrozumianych pojęć w JavaScript, ponieważ zachowuje się trochę inaczej z miejsca na miejsce. Po prostu, this odnosi się do "właściciela" funkcji, którą aktualnie wykonujemy.

this pomaga uzyskać bieżący obiekt (A.k. a. execution context), z którym pracujemy. Jeśli rozumiesz, w którym obiekcie jest wykonywana bieżąca funkcja, możesz łatwo zrozumieć, co to jest current this

var val = "window.val"

var obj = {
    val: "obj.val",
    innerMethod: function () {
        var val = "obj.val.inner",
            func = function () {
                var self = this;
                return self.val;
            };

        return func;
    },
    outerMethod: function(){
        return this.val;
    }
};

//This actually gets executed inside window object 
console.log(obj.innerMethod()()); //returns window.val

//Breakdown in to 2 lines explains this in detail
var _inn = obj.innerMethod();
console.log(_inn()); //returns window.val

console.log(obj.outerMethod()); //returns obj.val

Powyżej tworzymy 3 zmienne o tej samej nazwie "val". Jeden w kontekście globalnym, jeden wewnątrz obj, a drugi wewnątrz innerMethod obj. JavaScript rozwiązuje identyfikatory w określonym kontekście, przechodząc w górę łańcucha zakresu z lokalnego go global.


kilka miejsc, w których można wyróżnić this

Wywołanie metody obiektu

var status = 1;
var helper = {
    status : 2,
    getStatus: function () {
        return this.status;
    }
};

var theStatus1 = helper.getStatus(); //line1
console.log(theStatus1); //2

var theStatus2 = helper.getStatus;
console.log(theStatus2()); //1

Gdy line1 jest wykonywany, JavaScript ustanawia kontekst wykonania (EC) dla wywołania funkcji, ustawiając this na obiekt odwołujący się do whatever came przed ostatnim".". więc w ostatniej linii możesz zrozumieć, że {[11] } został wykonany w kontekście globalnym, który jest window.

Z Konstruktorem

this może być użyty do odwołania się do tworzonego obiektu

function Person(name){
    this.personName = name;
    this.sayHello = function(){
        return "Hello " + this.personName;
    }
}

var person1 = new Person('Scott');
console.log(person1.sayHello()); //Hello Scott

var person2 = new Person('Hugh');
var sayHelloP2 = person2.sayHello;
console.log(sayHelloP2()); //Hello undefined

Po wykonaniu nowego Person() tworzony jest zupełnie nowy obiekt. {[15] } jest wywołana i jej this jest ustawiona na odniesienie do tego nowego obiektu.

Wywołanie funkcji

function testFunc() {
    this.name = "Name";
    this.myCustomAttribute = "Custom Attribute";
    return this;
}

var whatIsThis = testFunc();
console.log(whatIsThis); //window

var whatIsThis2 = new testFunc();
console.log(whatIsThis2);  //testFunc() / object

console.log(window.myCustomAttribute); //Custom Attribute 

Jeśli pominiemy new słowo kluczowe, whatIsThis odnosi się do najbardziej globalnego kontekst może znaleźć(window)

Z Narzędziami obsługi zdarzeń

Jeśli Obsługa zdarzenia jest wbudowana, this odnosi się do obiektu globalnego

<script type="application/javascript">
    function click_handler() {
        alert(this); // alerts the window object
    }
</script>

<button id='thebutton' onclick='click_handler()'>Click me!</button>

Podczas dodawania obsługi zdarzenia przez JavaScript, this odnosi się do elementu DOM, który wygenerował Zdarzenie.


 4
Author: Nipuna,
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
2017-05-23 12:02:59

Wartość "this" zależy od "kontekstu", w którym funkcja jest wykonywana. Kontekstem może być dowolny obiekt lub obiekt globalny, np. okno.

Więc semantyka "tego" różni się od tradycyjnych języków OOP. I powoduje problemy: 1. gdy funkcja jest przekazywana do innej zmiennej (najprawdopodobniej callback); oraz 2. gdy zamknięcie jest wywoływane z metody członka klasy.

W obu przypadkach jest to ustawione na window.

 4
Author: Trombe,
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
2017-08-07 07:54:30

Kto mógłby to pomóc? (Większość nieporozumień "tego" w javascript wynika z faktu, że zazwyczaj nie jest on powiązany z Twoim obiektem, ale z bieżącym zakresem wykonywania-może to nie być dokładnie tak, jak to działa, ale zawsze tak mi się wydaje-zobacz artykuł, aby uzyskać pełne wyjaśnienie)

 2
Author: Simon Groenewolt,
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
2010-06-27 13:15:45

Trochę informacji o to słowo kluczowe

Zalogujmy this słowo kluczowe do konsoli w zasięgu globalnym bez więcej kodu, ale

console.log(this)

W Klient / przeglądarka this słowo kluczowe to obiekt globalny, który jest window

console.log(this === window) // true

I

In Server / Node/Javascript runtime this słowo kluczowe jest również obiektem globalnym, który jest module.exports

console.log(this === module.exports) // true
console.log(this === exports) // true

Pamiętaj exports jest tylko odniesieniem do module.exports

 2
Author: unclexo,
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-07-25 07:04:35

To użycie dla zakresu tak jak to

  <script type="text/javascript" language="javascript">
$('#tbleName tbody tr').each(function{
var txt='';
txt += $(this).find("td").eq(0).text();
\\same as above but synatx different
var txt1='';
 txt1+=$('#tbleName tbody tr').eq(0).text();
alert(txt1)
});
</script>

Wartość txt1 i txt jest taka sama w powyższym przykładzie $(this)=$('#tbleName tbody tr') to to samo

 1
Author: PRADEEP SINGH Chundawat,
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-04-06 07:15:05

Summary this Javascript:

  • wartość this jest określona przez jak funkcja jest wywoływana Nie, gdzie została utworzona!
  • zazwyczaj wartość this jest określana przez obiekt, który znajduje się po lewej stronie kropki. (window w przestrzeni globalnej)
  • W event listeners wartość this odnosi się do elementu DOM, na którym zdarzenie zostało wywołane.
  • gdy funkcja in jest wywoływana ze słowem kluczowym new wartość this odnosi się do nowo utworzonego obiekt
  • możesz manipulować wartością this za pomocą funkcji: call, apply, bind

Przykład:

let object = {
  prop1: function () {console.log(this);}
}

object.prop1();   // object is left of the dot, thus this is object

const myFunction = object.prop1 // We store the function in the variable myFunction

myFunction(); // Here we are in the global space
              // myFunction is a property on the global object
              // Therefore it logs the window object
              
             

Przykładowe słuchacze zdarzeń:

document.querySelector('.foo').addEventListener('click', function () {
  console.log(this);   // This refers to the DOM element the eventListener was invoked from
})


document.querySelector('.foo').addEventListener('click', () => {
  console.log(this);  // Tip, es6 arrow function don't have their own binding to the this v
})                    // Therefore this will log the global object
.foo:hover {
  color: red;
  cursor: pointer;
}
<div class="foo">click me</div>

Przykładowy konstruktor:

function Person (name) {
  this.name = name;
}

const me = new Person('Willem');
// When using the new keyword the this in the constructor function will refer to the newly created object

console.log(me.name); 
// Therefore, the name property was placed on the object created with new keyword.
 0
Author: Willem van der Veen,
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-21 17:12:28