Bagaimana cara kerja kata kunci "ini"?

Jun 27 2010

Saya perhatikan bahwa tampaknya tidak ada penjelasan yang jelas tentang apa thiskata kunci itu dan bagaimana kata kunci itu digunakan dengan benar (dan salah) dalam JavaScript di situs Stack Overflow.

Saya telah menyaksikan beberapa perilaku yang sangat aneh dengannya dan gagal memahami mengapa hal itu terjadi.

Bagaimana cara thiskerjanya dan kapan harus digunakan?

Jawaban

1378 DanielTrebbien Jun 27 2010 at 20:15

Saya sarankan membaca Mike Barat 's artikel Ruang Lingkup dalam JavaScript ( cermin ) pertama. Ini adalah pengantar yang sangat baik dan bersahabat untuk konsep thisdan rantai lingkup di JavaScript.

Begitu Anda mulai terbiasa this, aturannya sebenarnya cukup sederhana. Standar ECMAScript 5.1 mendefinisikan this:

§11.1.1 Kata thiskunci

Kata thiskunci mengevaluasi ke nilai ThisBinding dari konteks eksekusi saat ini

ThisBinding adalah sesuatu yang dipelihara oleh penerjemah JavaScript saat mengevaluasi kode JavaScript, seperti register CPU khusus yang menyimpan referensi ke suatu objek. Penerjemah memperbarui ThisBinding setiap kali membuat konteks eksekusi di salah satu dari hanya tiga kasus yang berbeda:

1. Konteks eksekusi global awal

Ini adalah kasus untuk kode JavaScript yang dievaluasi di tingkat atas, misalnya ketika langsung di dalam <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>

Saat mengevaluasi kode dalam konteks eksekusi global awal, ThisBinding disetel ke objek global, window( §10.4.1.1 ).

2. Memasukkan kode eval

  • … Dengan panggilan langsung ke eval()ThisBinding tidak berubah; itu adalah nilai yang sama dengan ThisBinding dari konteks eksekusi panggilan ( §10.4.2 (2) (a)).

  • … Jika tidak dengan panggilan langsung ke eval()
    ThisBinding diatur ke objek global seolah-olah mengeksekusi dalam konteks eksekusi global awal ( §10.4.2 (1)).

§15.1.2.1.1 mendefinisikan apa itu panggilan langsung eval(). Pada dasarnya, eval(...)adalah panggilan langsung sedangkan sesuatu seperti (0, eval)(...)atau var indirectEval = eval; indirectEval(...);merupakan panggilan tidak langsung eval(). Lihat jawaban chuckj untuk (1, eval) ('this') vs eval ('this') di JavaScript? dan ECMA-262-5 Dmitry Soshnikov secara rinci. Bab 2. Mode Ketat. untuk saat Anda mungkin menggunakan eval()panggilan tidak langsung .

3. Memasukkan kode fungsi

Ini terjadi saat memanggil suatu fungsi. Jika suatu fungsi dipanggil pada suatu objek, seperti in obj.myMethod()atau padanannya obj["myMethod"](), maka ThisBinding diatur ke objek tersebut ( objdalam contoh; §13.2.1 ). Dalam kebanyakan kasus lain, ThisBinding disetel ke objek global ( §10.4.3 ).

Alasan untuk menulis "dalam kebanyakan kasus lain" adalah karena ada delapan ECMAScript 5 fungsi built-in yang memungkinkan ThisBinding ditentukan dalam daftar argumen. Fungsi-fungsi khusus ini mengambil apa yang disebut thisArgyang menjadi ThisBinding saat memanggil fungsi ( §10.4.3 ).

Fungsi bawaan khusus ini adalah:

  • 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 ] )

Dalam kasus Function.prototypefungsi, mereka dipanggil pada objek fungsi, tetapi daripada menyetel ThisBinding ke objek fungsi, ThisBinding diatur ke thisArg.

Dalam kasus Array.prototypefungsi, yang diberikan callbackfndipanggil dalam konteks eksekusi di mana ThisBinding diatur ke thisArgjika disediakan; jika tidak, ke objek global.

Itu adalah aturan untuk JavaScript biasa. Saat Anda mulai menggunakan pustaka JavaScript (misalnya jQuery), Anda mungkin menemukan bahwa fungsi pustaka tertentu memanipulasi nilai this. Pengembang pustaka JavaScript tersebut melakukan ini karena cenderung mendukung kasus penggunaan yang paling umum, dan pengguna pustaka biasanya menganggap perilaku ini lebih nyaman. Saat meneruskan fungsi callback yang merujuk thiske fungsi library, Anda harus merujuk ke dokumentasi untuk jaminan apa pun tentang berapa nilainya thissaat fungsi tersebut dipanggil.

Jika Anda bertanya-tanya bagaimana pustaka JavaScript memanipulasi nilai this, pustaka tersebut hanya menggunakan salah satu fungsi JavaScript bawaan yang menerima a thisArg. Anda juga dapat menulis fungsi Anda sendiri dengan menggunakan fungsi callback dan thisArg:

function doWork(callbackfn, thisArg) {
    //...
    if (callbackfn != null) callbackfn.call(thisArg);
}

Ada kasus khusus yang belum saya sebutkan. Saat membuat objek baru melalui newoperator, penerjemah JavaScript membuat objek baru yang kosong, menyetel beberapa properti internal, dan kemudian memanggil fungsi konstruktor pada objek baru tersebut. Jadi, ketika sebuah fungsi dipanggil dalam konteks konstruktor, nilainya thisadalah objek baru yang dibuat oleh penerjemah:

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);

Fungsi panah

Fungsi panah (diperkenalkan di ECMA6) mengubah cakupan this. Lihat pertanyaan kanonis yang ada, fungsi Panah vs deklarasi / ekspresi fungsi: Apakah setara / dapat ditukar? untuk informasi lebih lanjut. Tapi singkatnya:

Fungsi panah tidak memiliki this.... pengikatannya sendiri . Sebaliknya, pengidentifikasi tersebut diselesaikan dalam lingkup leksikal seperti variabel lainnya. Itu berarti bahwa di dalam fungsi panah, this... merujuk ke nilai-nilai thisdi lingkungan tempat fungsi panah didefinisikan.

Hanya untuk bersenang-senang, uji pemahaman Anda dengan beberapa contoh

Untuk mengungkapkan jawabannya, arahkan mouse ke kotak abu-abu terang.

  1. Berapakah nilai thispada garis yang ditandai? Mengapa?

window - Garis yang ditandai dievaluasi dalam konteks eksekusi global awal.

    if (true) {
        // What is `this` here?
    }
  1. Berapakah nilai thispada garis yang ditandai ketika obj.staticFunction()dieksekusi? Mengapa?

obj - Saat memanggil fungsi pada objek, ikatan ini diatur ke objek.

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);
  

  1. Berapakah nilai thispada garis yang ditandai? Mengapa?

window

Dalam contoh ini, penerjemah JavaScript memasukkan kode fungsi, tetapi karena myFun/ obj.myMethodtidak dipanggil pada objek, ThisBinding disetel ke window.

Ini berbeda dari Python, di mana mengakses metode ( obj.myMethod) membuat objek metode terikat .

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);
  

  1. Berapakah nilai thispada garis yang ditandai? Mengapa?

window

Yang ini rumit. Saat mengevaluasi kode eval, thisadalah obj. Namun, dalam kode eval, myFuntidak dipanggil pada suatu objek, jadi ThisBinding disetel ke windowuntuk panggilan tersebut.

 <!-- no snippet because, seemingly, eval doesn’t work in snippets -->

    function myFun() {
        return this; // What is `this` here?
    }
    var obj = {
        myMethod: function () {
            eval("myFun()");
        }
    };
  1. Berapakah nilai thispada garis yang ditandai? Mengapa?

obj

Baris myFun.call(obj);tersebut memanggil fungsi bawaan khusus Function.prototype.call(), yang menerima thisArgsebagai argumen pertama.

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);
  

168 Mahesha999 Jul 08 2013 at 00:32

Kata thiskunci berperilaku berbeda di JavaScript dibandingkan dengan bahasa lain. Dalam bahasa Berorientasi Objek, thiskata kunci mengacu pada instance kelas saat ini. Dalam JavaScript, nilai thisditentukan oleh konteks pemanggilan function ( context.function()) dan tempat pemanggilannya .

1. Saat digunakan dalam konteks global

Saat Anda menggunakan thisdalam konteks global, itu terikat ke objek global ( windowdi browser)

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

Ketika Anda menggunakan thisdi dalam fungsi yang didefinisikan dalam konteks global, thismasih terikat ke objek global karena fungsi tersebut sebenarnya membuat metode konteks global.

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

Di atas f1dibuat metode objek global. Jadi kita juga bisa memanggilnya pada windowobjek sebagai berikut:

function f()
{
    return this;
}

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

2. Saat digunakan di dalam metode objek

Ketika Anda menggunakan thiskata kunci di dalam metode objek, thisterikat ke objek yang melingkupi "langsung".

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

Di atas saya telah menempatkan kata langsung dalam tanda kutip ganda. Ini untuk membuat titik bahwa jika Anda menumpuk objek di dalam objek lain, maka thisterikat ke induk langsung.

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

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

Meskipun Anda menambahkan fungsi secara eksplisit ke objek sebagai metode, itu masih mengikuti aturan di atas, yang thismasih mengarah ke objek induk langsung.

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. Saat menjalankan fungsi tanpa konteks

Saat Anda menggunakan thisfungsi di dalam yang dipanggil tanpa konteks apa pun (yaitu bukan pada objek apa pun), itu terikat ke objek global ( windowdi browser) (bahkan jika fungsi itu didefinisikan di dalam objek).

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 

Mencoba semuanya dengan fungsi

Kita dapat mencoba poin di atas dengan fungsi juga. Namun ada beberapa perbedaan.

  • Di atas kami menambahkan anggota ke objek menggunakan notasi literal objek. Kita dapat menambahkan anggota ke fungsi dengan menggunakan this. untuk menentukannya.
  • Notasi literal objek membuat turunan dari objek yang dapat kita gunakan segera. Dengan fungsi kita mungkin perlu membuat instance-nya terlebih dahulu menggunakan newoperator.
  • Juga dalam pendekatan literal objek, kita dapat secara eksplisit menambahkan anggota ke objek yang sudah ditentukan menggunakan operator titik. Ini akan ditambahkan ke contoh tertentu saja. Namun saya telah menambahkan variabel ke prototipe fungsi sehingga itu tercermin dalam semua contoh fungsi.

Di bawah ini saya mencoba semua hal yang kami lakukan dengan Object dan di thisatasnya, tetapi dengan terlebih dahulu membuat fungsi alih-alih langsung menulis objek.

/********************************************************************* 
  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. Saat digunakan di dalam fungsi konstruktor .

Ketika fungsi digunakan sebagai konstruktor (yaitu ketika dipanggil dengan newkata kunci), thisbagian dalam badan fungsi menunjuk ke objek baru yang sedang dibangun.

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. Ketika digunakan fungsi di dalam yang didefinisikan pada rantai prototipe

Jika metode berada pada rantai prototipe objek, thisdi dalam metode tersebut mengacu pada objek tempat metode dipanggil, seolah-olah metode tersebut didefinisikan pada objek.

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. Di dalam fungsi call (), apply () dan bind ()

  • Semua metode ini didefinisikan di Function.prototype.
  • Metode ini memungkinkan untuk menulis fungsi satu kali dan memanggilnya dalam konteks yang berbeda. Dengan kata lain, mereka memungkinkan untuk menentukan nilai thisyang akan digunakan saat fungsi sedang dijalankan. Mereka juga mengambil parameter apa pun untuk diteruskan ke fungsi asli saat dipanggil.
  • fun.apply(obj1 [, argsArray])Menyetel obj1sebagai nilai thisinside fun()dan memanggil fun()elemen yang lewat argsArraysebagai argumennya.
  • fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- Ditetapkan obj1sebagai nilai thisinside fun()dan panggilan yang fun()lewat arg1, arg2, arg3, ...sebagai argumennya.
  • fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])- Mengembalikan referensi ke fungsi fundengan thiskesenangan di dalam terikat obj1dan parameter funterikat ke parameter yang ditentukan arg1, arg2, arg3,....
  • Sekarang perbedaan antara apply, calldan bindpasti sudah menjadi jelas. applymemungkinkan untuk menetapkan argumen agar berfungsi sebagai objek mirip larik, yaitu objek dengan lengthproperti numerik dan properti bilangan bulat non-negatif yang sesuai. Sedangkan callmemungkinkan untuk menentukan argumen ke fungsi secara langsung. Keduanya applydan callsegera memanggil fungsi dalam konteks yang ditentukan dan dengan argumen yang ditentukan. Di sisi lain, bindcukup kembalikan fungsi yang terikat ke nilai yang ditentukan thisdan argumen. Kita bisa menangkap referensi ke fungsi yang dikembalikan ini dengan menugaskannya ke variabel dan nanti kita bisa memanggilnya kapan saja.
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. thispenanganan acara di dalam

  • Saat Anda menetapkan fungsi secara langsung ke penangan peristiwa suatu elemen, penggunaan thislangsung di dalam fungsi penanganan peristiwa merujuk ke elemen yang sesuai. Penugasan fungsi langsung tersebut dapat dilakukan dengan menggunakan addeventListenermetode atau melalui metode pendaftaran acara tradisional seperti onclick.
  • Demikian pula, saat Anda menggunakan thislangsung di dalam properti event (seperti <button onclick="...this..." >) elemen, ini merujuk ke elemen.
  • Namun penggunaan thissecara tidak langsung melalui fungsi lain yang dipanggil di dalam fungsi penanganan acara atau properti acara menyelesaikan objek global window.
  • Perilaku yang sama di atas dicapai ketika kita melampirkan fungsi ke event handler menggunakan metode model Pendaftaran Peristiwa Microsoft attachEvent. Alih-alih menetapkan fungsi ke event handler (dan dengan demikian membuat metode fungsi elemen), ia memanggil fungsi pada acara (secara efektif memanggilnya dalam konteks global).

Saya sarankan untuk lebih baik mencoba ini di 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>

8. thisdalam fungsi panah ES6

Dalam fungsi panah, thisakan berperilaku seperti variabel umum: itu akan diwarisi dari ruang lingkup leksikal. Fungsi this, di mana fungsi panah ditentukan, akan menjadi fungsi panah this.

Jadi, itu perilaku yang sama seperti:

(function(){}).bind(this)

Lihat kode berikut:

const globalArrowFunction = () => {
  return this;
};

console.log(globalArrowFunction()); //window

const contextObject = {
  method1: () => {return this},
  method2: function(){
    return () => {return this};
  }
};

console.log(contextObject.method1()); //window

const contextLessFunction = contextObject.method1;

console.log(contextLessFunction()); //window

console.log(contextObject.method2()()) //contextObject

const innerArrowFunction = contextObject.method2();

console.log(innerArrowFunction()); //contextObject 
66 user3459110 Oct 26 2014 at 22:07

Javascript this

Pemanggilan fungsi sederhana

Pertimbangkan fungsi berikut:

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

Perhatikan bahwa kami menjalankan ini dalam mode normal, yaitu mode ketat tidak digunakan.

Saat dijalankan di browser, nilai thisakan dicatat sebagai window. Ini karena windowvariabel global dalam lingkup browser web.

Jika Anda menjalankan bagian kode yang sama ini di lingkungan seperti node.js, thisakan merujuk ke variabel global di aplikasi Anda.

Sekarang jika kita menjalankan ini dalam mode ketat dengan menambahkan pernyataan "use strict";ke awal deklarasi fungsi, thistidak akan lagi merujuk ke variabel global di salah satu lingkungan. Ini dilakukan untuk menghindari kebingungan dalam mode ketat. thisakan, dalam hal ini hanya log undefined, karena itu apa adanya, itu tidak didefinisikan.

Dalam kasus berikut, kita akan melihat bagaimana memanipulasi nilai this.

Memanggil fungsi pada suatu objek

Ada berbagai cara untuk melakukan ini. Jika Anda telah memanggil metode asli dalam Javascript like forEachand slice, Anda seharusnya sudah tahu bahwa thisvariabel dalam kasus itu mengacu Objectpada yang Anda panggil fungsi itu (Perhatikan bahwa dalam javascript, hampir semuanya adalah an Object, termasuk Arrays dan Functions). Ambil kode berikut ini sebagai contoh.

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

Jika sebuah Objectberisi properti yang menampung Function, properti itu disebut metode. Metode ini, ketika dipanggil, akan selalu thismengatur variabelnya ke variabel Objectterkait. Ini berlaku untuk mode ketat dan non-ketat.

Perhatikan bahwa jika metode disimpan (atau lebih tepatnya, disalin) di variabel lain, referensi ke thistidak lagi disimpan dalam variabel baru. Sebagai contoh:

// continuing with the previous code snippet

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

Mempertimbangkan skenario yang lebih umum praktis:

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

Kata newkunci

Pertimbangkan fungsi konstruktor di 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`

Bagaimana cara kerjanya? Nah, mari kita lihat apa yang terjadi saat kita menggunakan newkata kunci tersebut.

  1. Memanggil fungsi dengan newkata kunci akan segera menginisialisasi sebuah Objecttipe Person.
  2. Konstruktor ini Objectmemiliki konstruktornya disetel ke Person. Juga, perhatikan bahwa hanya typeof awalakan kembali Object.
  3. ObjectPrototipe baru ini akan diberi Person.prototype. Ini berarti bahwa metode atau properti apa pun dalam Personprototipe akan tersedia untuk semua instance Person, termasuk awal.
  4. Fungsi Personitu sendiri sekarang dipanggil; thismenjadi referensi ke objek yang baru dibangun awal.

Cukup mudah, eh?

Perhatikan bahwa spesifikasi ECMAScript resmi tidak menyatakan bahwa jenis fungsi seperti itu adalah constructorfungsi sebenarnya . Ini hanyalah fungsi normal, dan newdapat digunakan pada fungsi apa pun. Hanya saja kami menggunakannya seperti itu, jadi kami menyebutnya begitu saja.

Fungsi panggilan pada Fungsi: calldanapply

Jadi ya, karena functions juga Objects(dan sebenarnya variabel kelas satu dalam Javascript), bahkan fungsi memiliki metode yang ... yah, berfungsi sendiri.

Semua fungsi mewarisi dari global Function, dan dua dari banyak metodenya adalah calldan apply, dan keduanya dapat digunakan untuk memanipulasi nilai thisdalam fungsi yang memanggilnya.

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

Ini adalah contoh umum penggunaan call. Ini pada dasarnya mengambil parameter pertama dan menetapkan thisfungsi foosebagai referensi thisArg. Semua parameter lain yang diteruskan ke callditeruskan ke fungsi foosebagai argumen.
Jadi kode di atas akan masuk {myObj: "is cool"}, [1, 2, 3]ke konsol. Cara yang cukup bagus untuk mengubah nilai thisdalam fungsi apa pun.

applyhampir sama dengan callaccept yang hanya membutuhkan dua parameter: thisArgdan array yang berisi argumen untuk diteruskan ke fungsi. Jadi callpanggilan di atas bisa diterjemahkan applyseperti ini:

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

Perhatikan bahwa calldan applydapat menimpa nilai thispemanggilan metode set by dot yang telah kita diskusikan di poin kedua. Cukup sederhana :)

Mempersembahkan .... bind!

bindadalah saudara dari calldan apply. Ini juga merupakan metode yang diwarisi oleh semua fungsi dari Functionkonstruktor global dalam Javascript. Perbedaan antara binddan call/ applyadalah bahwa keduanya calldan applyakan benar-benar menjalankan fungsi tersebut. bind, di sisi lain, mengembalikan fungsi baru dengan thisArgdan argumentspra-setel. Mari kita ambil contoh untuk lebih memahami ini:

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]`

Lihat perbedaan di antara ketiganya? Ini halus, tetapi digunakan secara berbeda. Suka calldan apply, bindjuga akan mengganti nilai thisset dengan pemanggilan metode titik.

Perhatikan juga bahwa tidak satu pun dari ketiga fungsi ini melakukan perubahan apa pun ke fungsi aslinya. calldan applyakan mengembalikan nilai dari fungsi yang baru dibangun sementara bindakan mengembalikan fungsi yang baru dibangun itu sendiri, siap untuk dipanggil.

Hal ekstra, salin ini

Terkadang, Anda tidak menyukai kenyataan bahwa thisberubah dengan cakupan, terutama cakupan bersarang. Lihat contoh berikut.

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"
        });
    }
  };

Pada kode di atas, kita melihat bahwa nilai thisdiubah dengan cakupan bersarang, tetapi kita menginginkan nilai dari thiscakupan asli. Jadi kami 'menyalin' thiske thatdan menggunakan salinannya, bukan this. Pintar, ya?

Indeks:

  1. Apa yang ditahan thissecara default?
  2. Bagaimana jika kita memanggil fungsi tersebut sebagai metode dengan notasi Object-dot?
  3. Bagaimana jika kita menggunakan newkata kunci?
  4. Bagaimana kita memanipulasi thisdengan calldan apply?
  5. Menggunakan bind.
  6. Menyalin thisuntuk memecahkan masalah cakupan bersarang.
49 arunjitsingh Jun 27 2010 at 21:10

"ini" adalah tentang ruang lingkup. Setiap fungsi memiliki ruang lingkupnya sendiri, dan karena semua yang ada di JS adalah objek, bahkan fungsi dapat menyimpan beberapa nilai ke dalam dirinya sendiri menggunakan "ini". OOP 101 mengajarkan bahwa "ini" hanya berlaku untuk instance suatu objek. Oleh karena itu, setiap kali suatu fungsi dijalankan, "instance" baru dari fungsi tersebut memiliki arti baru "ini".

Kebanyakan orang menjadi bingung ketika mereka mencoba menggunakan "ini" di dalam fungsi penutupan anonim seperti:

(fungsi (nilai) {
    this.value = value;
    $ ('. some-elements'). each (function (elt) {
        elt.innerHTML = this.value; // uh oh!! mungkin tidak terdefinisi
    });
}) (2);

Jadi di sini, di dalam each (), "this" tidak memiliki "nilai" yang Anda harapkan (dari

this.value = value;
di atasnya). Jadi, untuk mengatasi masalah ini (tidak ada permainan kata-kata), pengembang dapat:

(fungsi (nilai) {
    var self = ini; // uang receh
    self.value = nilai;
    $ ('. some-elements'). each (function (elt) {
        elt.innerHTML = self.value; // Fiuh !! == 2
    });
}) (2);

Cobalah; Anda akan mulai menyukai pola pemrograman ini

18 carlodurso Oct 30 2014 at 10:58

Sejak utas ini naik, saya telah mengumpulkan beberapa poin untuk pembaca yang baru thismengenal topik.

Bagaimana nilai thisditentukan?

Kami menggunakan ini mirip dengan cara kami menggunakan kata ganti dalam bahasa alami seperti bahasa Inggris: “John berlari cepat karena dia mencoba mengejar kereta.” Sebaliknya kita bisa menulis "... John sedang mencoba naik kereta".

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 tidak diberi nilai sampai sebuah objek memanggil fungsi di mana ia didefinisikan. Dalam lingkup global, semua variabel dan fungsi global ditentukan pada windowobjek. Oleh karena itu, thisdalam fungsi global mengacu pada (dan memiliki nilai) windowobjek global .

Ketika use strict, thisdalam fungsi global dan anonim yang tidak terikat ke objek apa pun memiliki nilai undefined.

Kata thiskunci paling disalahpahami ketika: 1) kami meminjam metode yang menggunakan this, 2) kami menetapkan metode yang digunakan thisuntuk variabel, 3) fungsi yang digunakan thisditeruskan sebagai fungsi panggilan balik, dan 4) thisdigunakan di dalam closure - fungsi batin. (2)

Apa yang menahan masa depan

Didefinisikan dalam ECMA Script 6 , fungsi panah mengadopsi thispengikatan dari lingkup penutup (fungsi atau global).

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!

Meskipun fungsi panah memberikan alternatif untuk digunakan bind(), penting untuk dicatat bahwa mereka pada dasarnya menonaktifkan thismekanisme tradisional untuk mendukung pelingkupan leksikal yang lebih dipahami secara luas. (1)


Referensi:

  1. ini & Prototipe Objek , oleh Kyle Simpson. © 2014 Getify Solutions.
  2. javascriptissexy.com - http://goo.gl/pvl0GX
  3. Angus Croll - http://goo.gl/Z2RacU
18 Seph Oct 07 2013 at 02:46

thisdalam JavaScript selalu mengacu pada 'pemilik' dari fungsi yang sedang dijalankan .

Jika tidak ada pemilik eksplisit yang ditentukan, maka pemilik paling atas, objek jendela, direferensikan.

Jadi jika saya melakukannya

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

element.onclick = someKindOfFunction;

thisakan merujuk ke objek elemen. Tapi hati-hati, banyak orang yang melakukan kesalahan ini.

<element onclick="someKindOfFunction()">

Dalam kasus terakhir, Anda hanya mereferensikan fungsi, bukan menyerahkannya ke elemen. Oleh karena itu, thisakan mengacu pada objek jendela.

15 blockhead Jun 27 2010 at 20:15

Setiap konteks eksekusi dalam javascript memiliki parameter ini yang disetel oleh:

  1. Bagaimana fungsi dipanggil (termasuk sebagai metode objek, penggunaan panggilan dan penerapan , penggunaan baru )
  2. Penggunaan bind
  3. Secara leksikal untuk fungsi panah (mereka mengadopsi ini dari konteks eksekusi luarnya)
  4. Apakah kode dalam mode ketat atau non-ketat
  5. Apakah kode tersebut dipanggil menggunakan eval

Anda dapat mengatur nilai ini menggunakan func.call, func.applyatau func.bind.

Secara default, dan apa yang membingungkan kebanyakan pemula, ketika pendengar disebut setelah acara dimunculkan pada elemen DOM, yang ini nilai fungsi adalah elemen DOM.

jQuery membuat hal ini sepele untuk diubah dengan jQuery.proxy.

11 ArmanMcHitarian Apr 23 2013 at 19:57

Daniel, penjelasan yang luar biasa! Beberapa kata tentang ini dan daftar thispenunjuk konteks eksekusi yang bagus dalam kasus penangan acara.

Dalam dua kata, thisdalam JavaScript menunjukkan objek dari siapa (atau dari konteks eksekusinya) fungsi saat ini dijalankan dan selalu hanya-baca, Anda tetap tidak dapat menyetelnya (upaya seperti itu akan berakhir dengan 'Invalid left-hand sisi dalam tugas 'pesan.

Untuk penangan peristiwa: penangan peristiwa sebaris, seperti <element onclick="foo">, menimpa penangan lain yang terpasang sebelumnya dan sebelumnya, jadi berhati-hatilah dan lebih baik tidak sama sekali dari delegasi peristiwa sebaris. Dan terima kasih kepada Zara Alaverdyan yang menginspirasi saya untuk daftar contoh ini melalui debat yang berbeda :)

  • 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)">
11 zangw Nov 29 2015 at 13:01

Berikut adalah salah satu sumber thismasuk yang bagus JavaScript.

Berikut ringkasannya:

  • global ini

    Di browser, pada lingkup global, thisadalah windowobjeknya

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

    Dalam nodemenggunakan repl, thisadalah namespace teratas. Anda bisa menyebutnya sebagai global.

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

    Dalam nodemengeksekusi dari skrip, thispada lingkup global dimulai sebagai objek kosong. Ini tidak sama denganglobal

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

Kecuali dalam kasus penangan kejadian DOM atau ketika a thisArgdisediakan (lihat lebih jauh di bawah), baik di node dan di browser yang menggunakan thisfungsi yang tidak dipanggil dengan newreferensi cakupan global ...

<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>

Jika Anda menggunakan use strict;, dalam hal thisiniundefined

<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>

Jika Anda memanggil fungsi dengan newyang thisakan menjadi konteks baru, itu tidak akan referensi global 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>
  • prototipe ini

Fungsi yang Anda buat menjadi objek fungsi. Mereka secara otomatis mendapatkan prototypeproperti khusus , yang merupakan sesuatu yang dapat Anda tetapkan nilainya. Saat Anda membuat instance dengan memanggil fungsi newAnda, Anda mendapatkan akses ke nilai yang Anda tetapkan ke prototypeproperti. Anda mengakses nilai-nilai itu menggunakan this.

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

Thing.prototype.foo = "bar";

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

Biasanya kesalahan untuk menetapkan array atau objek pada file prototype. Jika Anda ingin setiap instance memiliki lariknya sendiri, buatlah dalam fungsi, bukan prototipe.

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 []
  • keberatan ini

Anda dapat menggunakan thisfungsi apa pun pada objek untuk merujuk ke properti lain pada objek itu. Ini tidak sama dengan instance yang dibuat dengan new.

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

obj.logFoo(); //logs "bar"
  • Acara DOM ini

Dalam event handler DOM HTML, thisselalu ada referensi ke elemen DOM tempat kejadian dilampirkan

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();

Kecuali Anda bindkonteksnya

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 ini

Di dalam atribut HTML di mana Anda dapat meletakkan JavaScript, thisadalah referensi ke elemen.

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

Anda dapat menggunakan evaluntuk mengakses this.

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

var thing = new Thing();
thing.logFoo();
  • dengan ini

Anda dapat menggunakan withuntuk menambah thiscakupan saat ini untuk membaca dan menulis ke nilai thistanpa merujuk thissecara eksplisit.

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 ini

jQuery di banyak tempat akan thismerujuk ke elemen 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 ArupHore Jan 31 2017 at 15:29

Ada banyak kebingungan tentang bagaimana kata kunci "ini" diinterpretasikan dalam JavaScript. Mudah-mudahan artikel ini akan meletakkan semua itu untuk beristirahat sekali dan untuk selamanya. Dan masih banyak lagi. Harap baca seluruh artikel dengan cermat. Diperingatkan bahwa artikel ini panjang.

Terlepas dari konteks penggunaannya, "ini" selalu merujuk pada "objek saat ini" dalam Javascript. Namun, apa yang dimaksud dengan "objek saat ini" berbeda menurut konteksnya . The konteks mungkin persis 1 dari 6 berikut:

  1. Global (yaitu Di luar semua fungsi)
  2. Panggilan Inside Direct "Non Bound Function" (yaitu fungsi yang belum terikat dengan memanggil functionName.bind )
  3. Inside Indirect "Fungsi Tidak Terikat" Panggil melalui functionName.call dan functionName.apply
  4. Di dalam Panggilan "Bound Function" (yaitu fungsi yang telah diikat dengan memanggil functionName.bind )
  5. Sementara Pembuatan Objek melalui "baru"
  6. Di dalam event handler DOM Inline

Uraian berikut menjelaskan setiap konteks ini satu per satu:

  1. Konteks Global (yaitu Di luar semua fungsi):

    Di luar semua fungsi (yaitu dalam konteks global) "objek saat ini" (dan karenanya nilai "ini" ) selalu merupakan objek "jendela" untuk browser.

  2. Panggilan Inside Direct "Fungsi Tidak Terikat" :

    Di dalam Panggilan "Fungsi Tidak Terikat" Langsung, objek yang memanggil panggilan fungsi menjadi "objek saat ini" (dan karenanya menjadi nilai "ini" ). Jika suatu fungsi dipanggil tanpa objek saat ini eksplisit , objek saat ini adalah objek "jendela" (Untuk Mode Non Ketat) atau tidak ditentukan (Untuk Mode Ketat). Setiap fungsi (atau variabel) yang didefinisikan dalam Konteks Global secara otomatis menjadi properti dari objek "jendela". Misalnya Misalkan fungsi didefinisikan dalam Konteks Global sebagai

    function UserDefinedFunction(){
        alert(this)
        }
    

    itu menjadi properti objek jendela, seolah-olah Anda telah mendefinisikannya sebagai

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

    Dalam "Non Strict Mode", Memanggil / Memanggil fungsi ini secara langsung melalui "UserDefinedFunction ()" akan secara otomatis memanggil / memanggilnya sebagai "window.UserDefinedFunction ()" membuat "jendela" sebagai "objek saat ini" (dan karenanya nilai " ini " ) dalam " UserDefinedFunction ". Memasukkan fungsi ini dalam" Non Strict Mode "akan menghasilkan

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

    Dalam "Strict Mode", Memanggil / Memanggil fungsi secara langsung melalui "UserDefinedFunction ()" akan "TIDAK" secara otomatis memanggil / memanggilnya sebagai "window.UserDefinedFunction ()". Oleh karena itu, "objek saat ini" (dan nilai "ini" ) dalam "UserDefinedFunction" tidak akan ditentukan . Memanggil fungsi ini dalam "Mode Ketat" akan menghasilkan hal berikut

    UserDefinedFunction() // displays undefined
    

    Namun, memanggilnya secara eksplisit menggunakan objek jendela akan menghasilkan sebagai berikut

    window.UserDefinedFunction() // "always displays [object Window]   irrespective of mode."
    

    Mari kita lihat contoh lainnya. Silakan lihat kode berikut

     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
    

    Dalam contoh di atas kita melihat bahwa ketika "UserDefinedFunction" dipanggil melalui o1 , "this" mengambil nilai o1 dan nilai propertinya "a" dan "b" ditampilkan. Nilai "c" dan "d" ditampilkan sebagai tidak terdefinisi karena o1 tidak menentukan properti ini

    Demikian pula ketika "UserDefinedFunction" itu dipanggil melalui o2 , "ini" mengambil nilai o2 dan nilai properti nya "c" dan "d" mendapatkan tampil pada display nilai "a" dan "b" yang ditampilkan sebagai terdefinisi sebagai o2 tidak tidak mendefinisikan properti ini.

  3. Panggil "Fungsi Tidak Terikat" Di Dalam Tidak Langsung melalui functionName.call dan functionName.apply :

    Ketika "Fungsi Tidak Terikat" dipanggil melalui functionName.call atau functionName.apply , "objek saat ini" (dan karenanya nilai "ini" ) disetel ke nilai parameter "ini" (parameter pertama) yang diteruskan ke panggilan / terapkan . Kode berikut menunjukkan hal yang sama.

    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
    

    Kode di atas dengan jelas menunjukkan bahwa nilai "ini" untuk setiap "Fungsi NON Bound" dapat diubah melalui panggilan / penerapan . Selain itu, jika parameter "ini" tidak secara eksplisit diteruskan ke panggilan / penerapan , "objek saat ini" (dan karenanya nilai "ini") disetel ke "jendela" dalam mode Tidak ketat dan "tidak ditentukan" dalam mode ketat.

  4. Di dalam Panggilan "Bound Function" (yaitu fungsi yang telah diikat dengan memanggil functionName.bind ):

    Fungsi terikat adalah fungsi yang nilai "ini" -nya telah diperbaiki. Kode berikut menunjukkan bagaimana "ini" bekerja dalam kasus fungsi terikat

    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
    

    Seperti yang diberikan dalam kode di atas, nilai "ini" untuk setiap "Fungsi Terikat" TIDAK DAPAT diubah melalui panggilan / penerapan . Selain itu, jika parameter "ini" tidak secara eksplisit dikirimkan untuk mengikat, "objek saat ini" (dan karenanya nilai "ini" ) disetel ke "jendela" dalam mode Tidak ketat dan "tidak ditentukan" dalam mode ketat. Satu hal lagi. Mengikat fungsi yang sudah terikat tidak mengubah nilai "ini" . Ini tetap ditetapkan sebagai nilai yang ditetapkan oleh fungsi mengikat pertama.

  5. Sedangkan Pembuatan Objek melalui "baru" :

    Di dalam fungsi konstruktor, "objek saat ini" (dan karenanya nilai "ini" ) merujuk objek yang saat ini sedang dibuat melalui "baru" terlepas dari status mengikat fungsi tersebut. Namun jika konstruktor adalah fungsi terikat, ia akan dipanggil dengan set argumen yang telah ditentukan sebagai set untuk fungsi terikat.

  6. Di dalam event handler DOM Inline :

    Silakan lihat Snippet HTML berikut

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

    The "ini" di contoh di atas merujuk pada "tombol" elemen dan "div" elemen masing-masing.

    Dalam contoh pertama, warna font tombol akan disetel menjadi putih saat diklik.

    Dalam contoh kedua ketika elemen "div" diklik, itu akan memanggil fungsi OnDivClick dengan parameter kedua yang mereferensikan elemen div yang diklik. Namun nilai "ini" dalam OnDivClick TIDAK AKAN mereferensikan elemen div yang diklik . Ini akan ditetapkan sebagai "objek window" atau "tidak terdefinisi" di Non ketat dan ketat Mode masing-masing (jika OnDivClick adalah fungsi terikat ) atau set ke nilai Bound telah ditetapkan (jika OnDivClick adalah fungsi terikat )

Berikut ini ringkasan keseluruhan artikel

  1. Global Context "ini" selalu mengacu pada "jendela" objek

  2. Setiap kali suatu fungsi dipanggil, itu dipanggil dalam konteks objek ( "objek saat ini" ). Jika objek saat ini tidak disediakan secara eksplisit, objek saat ini adalah "objek jendela" dalam Mode Ketat NON dan "tidak ditentukan" dalam Mode Ketat secara default.

  3. Nilai "ini" dalam fungsi Tidak Terikat adalah referensi ke objek dalam konteks di mana fungsi tersebut dipanggil ( "objek saat ini" )

  4. Nilai "ini" dalam fungsi Tidak Terikat dapat diganti dengan memanggil dan menerapkan metode fungsi.

  5. Nilai "ini" ditetapkan untuk fungsi Terikat dan tidak dapat diganti dengan metode panggilan dan penerapan fungsi.

  6. Fungsi mengikat dan sudah terikat tidak mengubah nilai "ini". Ini tetap ditetapkan sebagai nilai yang ditetapkan oleh fungsi mengikat pertama.

  7. Nilai "ini" dalam konstruktor adalah objek yang dibuat dan diinisialisasi

  8. Nilai "ini" dalam pengendali kejadian DOM sebaris merujuk ke elemen yang diberikan pengendali kejadian.

9 DmitriPavlutin Nov 08 2016 at 19:17

Mungkin artikel paling rinci dan komprehensif tentang thisadalah sebagai berikut:

Penjelasan lembut tentang kata kunci 'ini' dalam JavaScript

Ide di baliknya thisadalah untuk memahami bahwa jenis pemanggilan fungsi memiliki kepentingan yang signifikan dalam menetapkan thisnilai.


Saat mengalami kesulitan mengidentifikasi this, jangan tanyakan pada diri Anda:

Dari mana thisdiambil ?

tapi jangan bertanya pada diri sendiri:

Bagaimana fungsi tersebut dipanggil ?

Untuk fungsi panah (kasus khusus transparansi konteks) tanyakan pada diri Anda:

Nilai apa yang memiliki thisfungsi panah didefinisikan ?

Pola pikir ini benar saat menghadapi thisdan akan menyelamatkan Anda dari sakit kepala.

7 JamesDrinkard Jul 13 2016 at 02:03

Ini adalah penjelasan terbaik yang pernah saya lihat: Pahami JavaScripts ini dengan Kejelasan

The ini referensi SELALU mengacu pada (dan memegang nilai) obyek-a tunggal objek-dan biasanya digunakan di dalam fungsi atau metode, meskipun dapat digunakan di luar fungsi dalam lingkup global. Perhatikan bahwa saat kita menggunakan mode ketat, ini memegang nilai tak terdefinisi dalam fungsi global dan fungsi anonim yang tidak terikat ke objek apa pun.

Ada Empat Skenario mana ini dapat membingungkan:

  1. Ketika kita mengirimkan metode (yang menggunakan ini ) sebagai argumen untuk digunakan sebagai fungsi panggilan balik.
  2. Saat kita menggunakan fungsi bagian dalam (penutupan). Penting untuk diperhatikan bahwa closures tidak dapat mengakses fungsi luar variabel ini dengan menggunakan kata kunci ini karena variabel ini hanya dapat diakses oleh fungsi itu sendiri, bukan oleh fungsi dalam.
  3. Ketika metode yang bergantung pada ini ditetapkan ke variabel di seluruh konteks, dalam hal ini referensi objek lain dari yang dimaksudkan semula.
  4. Saat menggunakan ini bersama dengan metode bind, apply, dan call.

Dia memberikan contoh kode, penjelasan, dan solusi, yang menurut saya sangat membantu.

6 Nipuna Aug 09 2014 at 16:22

thisadalah salah satu konsep yang disalahpahami dalam JavaScript karena perilakunya sedikit berbeda dari satu tempat ke tempat lain. Sederhananya, thismengacu pada "pemilik" dari fungsi yang sedang kita jalankan .

thismembantu untuk mendapatkan objek saat ini (alias konteks eksekusi) yang kita kerjakan. Jika Anda memahami di objek mana fungsi saat ini dijalankan, Anda dapat dengan mudah memahami apa itu saat thisini

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

Di atas kami membuat 3 variabel dengan nama yang sama 'val'. Satu dalam konteks global, satu di dalam obj dan yang lainnya di dalam innerMethod of obj. JavaScript menyelesaikan pengenal dalam konteks tertentu dengan menaikkan rantai cakupan dari lokal go global.


Beberapa tempat yang thisbisa dibedakan

Memanggil metode objek

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

Saat baris1 dijalankan, JavaScript membuat konteks eksekusi (EC) untuk pemanggilan fungsi, menyetel thiske objek yang direferensikan oleh apa pun yang datang sebelum "." . jadi di baris terakhir Anda dapat memahami bahwa a()dieksekusi dalam konteks global yaitu file window.

Dengan Konstruktor

this dapat digunakan untuk merujuk ke objek yang sedang dibuat

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

Saat new Person()dijalankan, objek yang benar-benar baru dibuat. Persondipanggil dan thisdisetel untuk mereferensikan objek baru itu.

Panggilan fungsi

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 

Jika kami melewatkan newkata kunci, whatIsThislihat konteks paling global yang dapat ditemukannya ( window)

Dengan penangan acara

Jika pengendali kejadian sebaris, thismengacu pada objek global

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

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

Saat menambahkan pengendali peristiwa melalui JavaScript, thismengacu pada elemen DOM yang menghasilkan peristiwa tersebut.


  • Anda juga dapat memanipulasi konteks menggunakan .apply() .call()dan.bind()
  • Proksi JQuery adalah cara lain yang dapat Anda gunakan untuk memastikan ini dalam suatu fungsi akan menjadi nilai yang Anda inginkan. (Periksa Memahami penggunaan $ .proxy () , jQuery.proxy () )
  • Apa var that = thisartinya di JavaScript
6 mrmaclean89 Sep 17 2017 at 05:11

Dalam istilah pseudoklasik, cara banyak kuliah mengajarkan kata kunci 'ini' adalah sebagai objek yang dipakai oleh kelas atau konstruktor objek. Setiap kali objek baru dibangun dari sebuah kelas, bayangkan bahwa di bawah tenda sebuah instance lokal dari objek 'ini' dibuat dan dikembalikan. Saya ingat itu diajarkan seperti ini:

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 Trombe Jul 03 2017 at 17:07

Nilai "ini" bergantung pada "konteks" tempat fungsi tersebut dijalankan. Konteksnya dapat berupa objek apa pun atau objek global, yaitu jendela.

Jadi Semantik dari "ini" berbeda dari bahasa OOP tradisional. Dan itu menyebabkan masalah: 1. ketika suatu fungsi dilewatkan ke variabel lain (kemungkinan besar, callback); dan 2. ketika closure dipanggil dari metode anggota kelas.

Dalam kedua kasus, ini disetel ke jendela.

4 SimonGroenewolt Jun 27 2010 at 20:15

Apa yang bisa membantu ini ? (Sebagian besar kebingungan 'ini' di javascript berasal dari fakta bahwa itu umumnya tidak terkait dengan objek Anda, tetapi ke ruang lingkup eksekusi saat ini - itu mungkin tidak persis seperti cara kerjanya tetapi selalu terasa seperti itu bagi saya - lihat artikel untuk penjelasan lengkapnya)

3 unclexo Jul 25 2018 at 14:04

Sedikit info tentang kata kunci ini

Mari catat thiskata kunci ke konsol dalam lingkup global tanpa kode lagi selain

console.log(this)

Dalam Client / Browser this kata kunci adalah obyek global yaituwindow

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

dan

Dalam Server / Node / Javascript runtime this kata kunci juga merupakan objek global yangmodule.exports

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

Yang perlu diingat exportshanyalah referensi kemodule.exports

1 PRADEEPSINGHChundawat Apr 06 2016 at 14:15

ini digunakan untuk Scope seperti ini

  <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>

nilai txt1 dan txt sama pada contoh di atas $ (this) = $ ('# tbleName tbody tr') sama

1 gman Jan 29 2019 at 01:37

Saya memiliki pandangan berbeda thisdari jawaban lain yang saya harap bermanfaat.

Salah satu cara untuk melihat JavaScript adalah dengan melihat bahwa hanya ada 1 cara untuk memanggil fungsi 1 . ini

functionObject.call(objectForThis, arg0, arg1, arg2, ...);

Selalu ada nilai yang diberikan objectForThis.

Yang lainnya adalah untuk gula sintaksis functionObject.call

Jadi, segala sesuatu yang lain dapat dijelaskan dengan cara menerjemahkannya ke dalam functionObject.call.

Jika Anda hanya memanggil suatu fungsi maka thisadalah "objek global" yang di browser adalah jendela

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

foo();  // this is the window object

Dengan kata lain,

foo();

diterjemahkan secara efektif ke dalam

foo.call(window);

Perhatikan bahwa jika Anda menggunakan mode ketat maka thisakanundefined

'use strict';

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

foo();  // this is the window object

yang berarti

Dengan kata lain,

foo();

diterjemahkan secara efektif ke dalam

foo.call(undefined);

Di JavaScript ada operator seperti +dan -dan *. Ada juga operator titik.

The .Operator bila digunakan dengan fungsi di sebelah kanan dan objek di sebelah kiri secara efektif berarti "lulus objek sebagai thisfungsi.

Contoh

const bar = {
  name: 'bar',
  foo() { 
    console.log(this); 
  },
};

bar.foo();  // this is bar

Dengan kata lain bar.foo()diterjemahkan menjadiconst temp = bar.foo; temp.call(bar);

Perhatikan bahwa tidak masalah bagaimana fungsi itu dibuat (kebanyakan ...). Semua ini akan memberikan hasil yang sama

const bar = {
  name: 'bar',
  fn1() { console.log(this); },
  fn2: function() { console.log(this); },
  fn3: otherFunction,
};

function otherFunction() { console.log(this) };

bar.fn1();  // this is bar
bar.fn2();  // this is bar
bar.fn3();  // this is bar

Sekali lagi ini semua hanya untuk gula sintaksis

{ const temp = bar.fn1; temp.call(bar); }
{ const temp = bar.fn2; temp.call(bar); }
{ const temp = bar.fn3; temp.call(bar); }

Kerutan lainnya adalah rantai prototipe. Saat Anda menggunakan a.bJavaScript, pertama-tama, lihat objek yang direferensikan secara langsung oleh auntuk properti tersebut b. Jika btidak ditemukan pada objek maka JavaScript akan mencari di prototipe objek untuk menemukannya b.

Ada berbagai cara untuk mendefinisikan prototipe objek, yang paling umum di tahun 2019 adalah classkata kunci. Untuk tujuan thismeskipun itu tidak masalah. Yang penting adalah seperti yang terlihat di objek auntuk properti bjika menemukan properti bpada objek atau dalam rantai prototipe itu jika bakhirnya menjadi fungsi maka aturan yang sama seperti di atas berlaku. bReferensi fungsi akan dipanggil menggunakan callmetode dan meneruskan asebagai objectForThis seperti yang ditunjukkan di bagian atas jawaban ini.

Sekarang. Mari kita bayangkan kita membuat sebuah fungsi yang secara eksplisit disetel thissebelum memanggil fungsi lain dan kemudian memanggilnya dengan .operator (titik)

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

function bar() {
  const objectForThis = {name: 'moo'}
  foo.call(objectForThis);  // explicitly passing objectForThis
}

const obj = {
  bar,
};

obj.bar();  

Mengikuti terjemahan untuk digunakan call, obj.bar()menjadi const temp = obj.bar; temp.call(obj);. Ketika kita memasuki barfungsi yang kita panggil footetapi kita secara eksplisit mengirimkan objek lain untuk objectForThis jadi ketika kita tiba di foo thisadalah objek dalam itu.

Inilah yang dilakukan oleh keduanya binddan =>fungsi secara efektif. Mereka lebih banyak gula sintaksis. Mereka secara efektif membangun fungsi baru yang tidak terlihat persis seperti di baratas yang secara eksplisit ditetapkan thissebelum memanggil fungsi apa pun yang ditentukan. Dalam kasus mengikat thisdiatur ke apa pun yang Anda berikan bind.

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

const bar = foo.bind({name: 'moo'});

// bind created a new invisible function that calls foo with the bound object.

bar();  

// the objectForThis we are passing to bar here is ignored because
// the invisible function that bind created will call foo with with
// the object we bound above

bar.call({name: 'other'});

Perhatikan bahwa jika functionObject.bindtidak ada kita bisa membuatnya sendiri seperti ini

function bind(fn, objectForThis) {
  return function(...args) {
    return fn.call(objectForthis, ...args);
  };
}

dan kemudian kita bisa menyebutnya seperti ini

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

const bar = bind(foo, {name:'abc'});

Fungsi panah, =>operator adalah gula sintaksis untuk mengikat

const a = () => {console.log(this)};

sama dengan

const tempFn = function() {console.log(this)}; 
const a = tempFn.bind(this);

Sama seperti bind, fungsi baru yang tidak terlihat dibuat yang memanggil fungsi yang diberikan dengan nilai terikat objectForThistetapi tidak seperti bindobjek yang akan diikat, bersifat implisit. Apapun yang thisterjadi ketika =>operator digunakan.

Jadi, seperti aturan di atas

const a = () => { console.log(this); }  // this is the global object
'use strict';
const a = () => { console.log(this); }  // this is undefined
function foo() {
  return () => { console.log(this); }
}

const obj = {
  foo,
};
const b = obj.foo();
b();

obj.foo()diterjemahkan const temp = obj.foo; temp.call(obj);yang berarti operator panah di dalam fooakan mengikat objke fungsi tak terlihat baru dan mengembalikan fungsi tak terlihat baru yang ditetapkan ke b. b()akan bekerja seperti biasa b.call(window)atau b.call(undefined)memanggil fungsi tak terlihat baru yang foodibuat. Fungsi tak terlihat itu mengabaikan yang thisditeruskan ke dalamnya dan diteruskan objsebagai objectForThis` ke fungsi panah.

Kode di atas diterjemahkan menjadi

function foo() {
  function tempFn() {
    console.log(this);
  }
  return tempFn.bind(this);
}

const obj = {
  foo,
};
const b = obj.foo();
b.call(window or undefined if strict mode);

1apply adalah fungsi lain yang mirip dengancall

functionName.apply(objectForThis, arrayOfArgs);

Tetapi pada ES6 secara konseptual Anda bahkan dapat menerjemahkannya ke dalam

functionName.call(objectForThis, ...arrayOfArgs);
WillemvanderVeen Aug 22 2018 at 00:12

Ringkasan thisJavascript:

  • Nilai thisditentukan oleh bagaimana fungsi tersebut dipanggil tidak, di mana ia dibuat!
  • Biasanya nilai thisditentukan oleh Objek yang berada di kiri titik. ( windowdi ruang global)
  • Dalam event listener, nilai thismerujuk ke elemen DOM tempat kejadian dipanggil.
  • Ketika dalam fungsi dipanggil dengan newkata kunci nilai thismerujuk ke objek yang baru dibuat
  • Anda dapat memanipulasi nilai thisdengan fungsi: call, apply,bind

Contoh:

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
              
             

Contoh pemroses acara:

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>

Contoh 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.

Lord May 20 2020 at 16:43

Untuk memahami "ini" dengan benar, seseorang harus memahami konteks dan ruang lingkup serta perbedaan di antara keduanya.

Lingkup : Dalam lingkup javascript terkait dengan visibilitas variabel, ruang lingkup dicapai melalui penggunaan fungsi. (Baca lebih lanjut tentang ruang lingkup)

Konteks : Konteks berhubungan dengan objek. Ini mengacu pada objek yang dimiliki suatu fungsi. Saat Anda menggunakan JavaScript kata kunci "ini", ini merujuk ke objek yang memiliki fungsi. Misalnya, di dalam suatu fungsi, saat Anda mengatakan: "this.accoutNumber", Anda merujuk ke properti "accoutNumber", yang dimiliki oleh objek yang memiliki fungsi tersebut.

Jika objek "myObj" memiliki metode yang disebut "getMyName", saat kata kunci JavaScript "ini" digunakan di dalam "getMyName", ini merujuk ke "myObj". Jika fungsi "getMyName" dijalankan dalam lingkup global, maka "ini" merujuk ke objek jendela (kecuali dalam mode ketat).

Sekarang mari kita lihat beberapa contoh:

    <script>
        console.log('What is this: '+this);
        console.log(this);
    </script>

Kode runnig abobve dalam output browser akan:

Menurut output Anda berada di dalam konteks objek jendela, juga terlihat bahwa prototipe jendela mengacu pada Objek.

Sekarang mari kita coba di dalam sebuah fungsi:

    <script>
        function myFunc(){
            console.log('What is this: '+this);
            console.log(this);
        }
        myFunc();
    </script>

Keluaran:

Outputnya sama karena kita mencatat variabel 'ini' dalam lingkup global dan kita mencatatnya dalam lingkup fungsional, kita tidak mengubah konteksnya. Dalam kedua kasus tersebut konteksnya sama, terkait dengan objek janda .

Sekarang mari buat objek kita sendiri. Dalam javascript, Anda dapat membuat objek dengan banyak cara.

 <script>
        var firstName = "Nora";
        var lastName = "Zaman";
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printNameGetContext:function(){
                console.log(firstName + " "+lastName);
                console.log(this.firstName +" "+this.lastName);
                return this;
            }
        }

      var context = myObj.printNameGetContext();
      console.log(context);
    </script>

Keluaran:

Jadi dari contoh di atas, kami menemukan bahwa kata kunci 'ini' mengacu pada konteks baru yang terkait dengan myObj, dan myObject juga memiliki rantai prototipe ke Objek.

Mari kita berikan contoh lain:

<body>
    <button class="btn">Click Me</button>
    <script>
        function printMe(){
            //Terminal2: this function declared inside window context so this function belongs to the window object.
            console.log(this);
        }
        document.querySelector('.btn').addEventListener('click', function(){
            //Terminal1: button context, this callback function belongs to DOM element 
            console.log(this);
            printMe();
        })
    </script>
</body>

keluaran: Masuk akal kan? (baca komentar)

Jika Anda kesulitan memahami contoh di atas, mari coba dengan callback kita sendiri;

<script>
        var myObj = {
            firstName:"Lord",
            lastName:'Baron',
            printName:function(callback1, callback2){
                //Attaching callback1 with this myObj context
                this.callback1 = callback1;
                this.callback1(this.firstName +" "+this.lastName)
                //We did not attached callback2 with myObj so, it's reamin with window context by default
                callback2();
                /*
                 //test bellow codes
                 this.callback2 = callback2;
                 this.callback2();
                */
            }
        }
        var callback2 = function (){
            console.log(this);
        }
        myObj.printName(function(data){
            console.log(data);
            console.log(this);
        }, callback2);
    </script>

keluaran:

Sekarang mari kita Pahami Cakupan, Diri, HIDUP dan INI bagaimana berperilaku

       var color = 'red'; // property of window
       var obj = {
           color:'blue', // property of window
           printColor: function(){ // property of obj, attached with obj
               var self = this;
               console.log('In printColor -- this.color: '+this.color);
               console.log('In printColor -- self.color: '+self.color);
               (function(){ // decleard inside of printColor but not property of object, it will executed on window context.
                    console.log(this)
                    console.log('In IIFE -- this.color: '+this.color);
                    console.log('In IIFE -- self.color: '+self.color); 
               })();

               function nestedFunc(){// decleard inside of printColor but not property of object, it will executed on window context.
                    console.log('nested fun -- this.color: '+this.color);
                    console.log('nested fun -- self.color: '+self.color);
               }

               nestedFunc(); // executed on window context
               return nestedFunc;
           }
       };

       obj.printColor()(); // returned function executed on window context
   </script> 

Outputnya cukup mengagumkan bukan?