[ Web Proxy ]
URL:
Viewing: https://id.javascript.info/object-methods [Back]  [Original]

Metode objek, "this"
ID

Kami ingin membuat proyek open source ini tersedia untuk orang-orang di seluruh dunia.

Bantu untuk menerjemahkan konten tutorial ini ke bahasa Anda!

    Cari pada Javascript.info:
    Cari di tutorial:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Metode objek, "this"

    Objek-objek biasanya dibuat untuk merepresentasikan benda di dunia nyata, seperti para pengguna, perintah dan sebagainya:

    let user = {
      name: "John",
      age: 30
    };

    Dan, di dunia nyata, seorang pengguna bisa bertindak: memilih sesuatu dari keranjang belanja, login, logout dan lain-lain.

    Tindakan-tindakan direpresentasikan dalam JavaScript dengan fungsi-fungsi dalam properti.

    Contoh metode

    Sebagai awalan, mari ajarkan user untuk bilang hello:

    let user = {
      name: "John",
      age: 30
    };
    
    user.sayHi = function() {
      alert("Hello!");
    };
    
    user.sayHi(); // Hello!

    Di sini kita hanya menggunakan sebuah fungsi ekspresi untuk membuat fungsi dan menugaskannya ke properti user.sayHi pada objek.

    Kemudian kita memanggil fungsi tersebut. Kini pengguna bisa berbicara!

    Sebuah fungsi yang mana merupakan properti dari sebuah objek disebut sebagai metode-nya.

    Jadi, di sini kita memiliki sebuah metode sayHi dari objekuser.

    Tentu saja, kita bisa menggunakan sebuah fungsi sebagai sebuah metode pra-deklarasi (pre-declared), seperti beriktu:

    let user = {
      // ...
    };
    
    // pertama, deklarasi
    function sayHi() {
      alert("Hello!");
    };
    
    // lalu tambbahkan sebagai sebuah metodes
    user.sayHi = sayHi;
    
    user.sayHi(); // Hello!
    Object-oriented programming

    Ketika kita menulis kode kita menggunakan objek-objek untuk merepresentasikan benda, itulah yang disebut sebagai object-oriented programming, disingkat menjadi: OOP.

    OOP adalah hal besar, sebuah sains yang sangat menarik. Bagaimana cara memilih entitas yang benar? bagaimana cara mengorganisir interaksi diantara mereka? Itulah arsitektur, dan terdapat buku yang bagus untuk topik itu, seperti Design Patterns: Elements of Reusable Object-Oriented Software oleh E. Gamma, R. Helm, R. Johnson, J. Vissides atau Object-Oriented Analysis and Design with Applications by G. Booch, and more.

    Metode ringkas

    Terdapat sebuah sintaks yang lebih pendek untuk metode-metode dalams sebuah penulisan (kode) objek:

    // objek-objek ini sama
    
    user = {
      sayHi: function() {
        alert("Hello");
      }
    };
    
    // metode ringkas terlihat lebih bagus, kan?
    user = {
      sayHi() { // sama seperti "sayHi: function()"
        alert("Hello");
      }
    };

    Seperti yang didemonstrasikan, kita bisa mengabaikan "function" dan hanya menuliskan sayHi().

    Sebenarnya, notasi-notasi tersebut tidak sepenuhnya sama. Ada beberapa perbedaan kecil yang berhubungan dengan object inheritance atau pewarisan objek (akan dibahas nanti), tetapi untuk sekarang hal-hal tersebut tidak terlalu penting. Dalam hampir kebanyakan kasus sintaks ringkas lebih disukai.

    this dalam metode

    Sudah umum bahwa sebuah metode objek perlu untuk mengakses informasi yang disimpan dalam objek untuk melakukan tugasnya.

    Contohnya, kode di dalam user.sayHi() bisa jadi membutuhkan nama dari user.

    Untuk mengakses objek yang bersangkutan, sebuah metode dapat menggunakan kata kunci this.

    Nilai dari this adalah objek sebelum (tanda) titik, yang mana sebelumnya memanggil metode tersebut.

    Sebagai contoh:

    let user = {
      name: "John",
      age: 30,
    
      sayHi() {
        // "this" adalah "objek yang sekarang"
        alert(this.name);
      }
    
    };
    
    user.sayHi(); // John

    Di sini selama ekseskusi user.sayHi(), nilai dari this akan menjadi user.

    Secara teknis, memungkingkan juga untuk mengakses objek tanpa this, dengan cara mereferensikannya melalui variabel luar:

    let user = {
      name: "John",
      age: 30,
    
      sayHi() {
        alert(user.name); // menggunakan "user" ketimbang "this"
      }
    
    };

    Namun kode yang demikian tidak dapat diandalkan. Jika kita memilih untuk menyalin user ke sebuah variabel lain, misalnya admin = user dan menimpa user dengan hal lain, akhirnya malah akan mengakses objek yang salah.

    Hal tersebut dicontohkan seperti berikut ini:

    let user = {
      name: "John",
      age: 30,
    
      sayHi() {
        alert( user.name ); // akan mengarah ke sebuah error
      }
    
    };
    
    
    let admin = user;
    user = null; // timpa/overwrite agar terlihat lebih jelas
    
    admin.sayHi(); // Uups! dalam sayHi(), nama yang lama sedang digunakan! error!

    Jika kita menggunakan this.name ketimbang user.name dalam alert, maka kodenya akhirnya berfungsi.

    this tidak ditemukan

    Dalam JavaScript, kata kunci this berperilaku tidak seperti kebanyak bahasa pemrograman lainnya. this juga bisa digunakan dalam fungsi apapun.

    Tidak ada syntax error dalam contoh berikut ini:

    function sayHi() {
      alert( this.name );
    }

    Nilai dari this dievaluasi selama proses run-time, tergantung dari konteksnya.

    Contohnya, di sini fungsi yang sama ditugaskan pada dua objek yang berbeda dan memiliki this dalam pemanggilannya:

    let user = { name: "John" };
    let admin = { name: "Admin" };
    
    function sayHi() {
      alert( this.name );
    }
    
    // menggunakan fungsi yang sama dalam dua objek
    user.f = sayHi;
    admin.f = sayHi;
    
    // panggilan-panggilan ini memiliki this yang berbeda
    // "this" dalam fungsi adalah objek "sebelum tanda titik"
    user.f(); // John  (this == user)
    admin.f(); // Admin  (this == admin)
    
    admin['f'](); // Admin (tanda titik atau kurung siku mengakses metode tersebut  bukan masalah)

    Aturannya sederhana: jika obj.f() dipanggil, maka this adalah obj selama pemanggilan f. Jadi antara user atau admin pada contoh di atas.

    Pemanggilan tanpa sebuah objek: this == undefined

    Kita bahkan bisa memanggil fungsi tanpa sebuah objek sama sekali:

    function sayHi() {
      alert(this);
    }
    
    sayHi(); // undefined

    Dalam kasus ini this adalah undefined di mode strict. Jika kita coba untuk mengakses this.name, akan menghasilkan sebuah error.

    Dalam mode non-strict nilai dari this dalam kasus demikian akan menjadi objek global (window dalam sebuah peramban, kita akan membahasnya lebih lanjut dalam bab Objek global). Ini adalah sebuah perilaku historis yang dibenahi oleh "use strict".

    Biasanya panggilan yang demikian adalah sebuah kesalahan programming. Jika terdapat this dalam sebuah fungsi, this tersebut kemungkinan besar akan dipanggil dalam konteks sebuah objek.

    Akibat dari this yang tidak terikat

    Jika kamu berasal dari bahasa pemrograman lain, mungkin saja kamu menggunakan gagasan sebuah pengikatan (bound) this, dimana metode-metode didefinisikan dalam sebuah objek selalu memiliki this yang merujuk pada objek itu.

    Dalam JavaScript this itu bebas, nilainya dieveluasi saat waktu pemanggilan dan tidak tergantung pada dimana metode tersebut di deklarasikan, namun lebih pada objek apa yang berada sebelum (tanda) titik.

    Konsep run-time mengeveluasi this memiliki kelebihan dan kekurangan sendiri. Di satu sisi, sebuah fungsi bisa digunakan ulang untuk objek-objek yang berbeda. Pada sisi sebaliknya, fleksibilitas yang besar membuat lebih banyak kemungkinan adanya kesalahan-kesalahan.

    Di sini posisi kita tidak untuk menghakimi apakah pilihan rancangan bahasa pemrograman ini baik atau buruk. Kita akan mengerti bagaimana bekerja dengan hal itu, serta bagaimana cara mendapatkan keuntungan dari hal tersebut dan menghindari adanya masalah.

    Fungsi arrow tidak memiliki this

    Fungsi-fungsi arrow itu istimewa: fungsi tersebut tidak memiliki this milik fungsi itu sendiri. Jika kita mereferensikan this dari fungsi demikian, hal itu didapat dari fungsi normal di luar.

    For instance, here arrow() uses this from the outer user.sayHi() method:

    let user = {
      firstName: "Ilya",
      sayHi() {
        let arrow = () => alert(this.firstName);
        arrow();
      }
    };
    
    user.sayHi(); // Ilya

    Itulah fitur istimewa dari fungsi arrow, fitur berguna ketika kita benar-benar tidak ingin memiliki sebuah this yang terpisah, namun kita mengambilnya dari luar lingkung tersebut. Selanjutnya dalam bab Membahas Kembali Fungsi Arrow kita akan mempelajari lebih dalam mengenai fungsi arrow.

    Ringkasan

    • Fungsi-fungsi yang disimpan dalam properti objek disebut sebagai metode.
    • Metode membuat objek dapat bertindak seperti object.doSomething().
    • Metode bisa mereferensikan ke objek sebagai this.

    Nilai dari this didefiniskan saat run-time.

    • Ketika sebuah fungsi dideklarasikan, fungsi tersebut bisa menggunakan this, tetapi this tersebut tidak memiliki nilai sampai fungsi tersebut dipanggil.
    • Sebuah fungsi bisa disalin di antara objek-objek.
    • Ketika sebuah fungsi dipanggil dalam sintaks metode: object.method(), nilai this selama pemanggilan adalah object.

    Mohon diingat bahwa fungsi arrow itu istimewa: fungsi tersebut tidak memiliki this. Ketika this diakses di dalam sebuah fungsi arrow, this itu diambil dari luar.

    Tugas

    pentingnya: 5

    Berikut ini adalah fungsi makeUser yang mengembalikan sebuah objek.

    Apa hasil dari mengakses ref? Mengapa demikian?

    function makeUser() {
      return {
        name: "John",
        ref: this
      };
    }
    
    let user = makeUser();
    
    alert( user.ref.name ); // Apa hasilnya?
    solusi

    Jawaban: error.

    Coba ini:

    function makeUser() {
      return {
        name: "John",
        ref: this
      };
    }
    
    let user = makeUser();
    
    alert( user.ref.name ); // Error: Tidak bisa membaca properti 'name' dari undefined

    Hal itu karena aturan-aturan yang mengatur this tidak melihat definisi objek. Yang penting hanya momen saat panggilan terjadi.

    Di sini nilai dari this dalam makeUser() adalah undefined, karena dipanggil sebagai sebuah fungsi, tidak sebagai sebuah metode dengan sintaks tanda titik.

    Nilai this adalah satu untuk keseluruhan fungsi, blok kode serta penulisan objek tidak mempengaruhi nilai tersebut.

    Jadi ref: this sebenarnya mengambil this yang sekarang dari fungsi tersebut.

    Berikut ini contoh kasus kebalikannya:

    function makeUser() {
      return {
        name: "John",
        ref() {
          return this;
        }
      };
    }
    
    let user = makeUser();
    
    alert( user.ref().name ); // John

    Kini kode itu berfugsi, karena user.ref() adalah sebuah metode. Dan nilai dari this ditentukan ke objek sebelum tanda titik ..

    pentingnya: 5

    Buatlah sebuah objek calculator dengan tiga metode:

    • read() mendorong kedua nilai dan menyimpan nilai-nilai tersebut sebagai properti objek.
    • sum() mengembalikan jumlah dari nilai-nilai yang disimpan.
    • mul() mengalikan nilai-nilai yang disimpan dan mengembalikan hasilnya.
    let calculator = {
      // ... your code ...
    };
    
    calculator.read();
    alert( calculator.sum() );
    alert( calculator.mul() );

    jalankan demonya

    Buka sandbox dengan tes.

    solusi
    let calculator = {
      sum() {
        return this.a + this.b;
      },
    
      mul() {
        return this.a * this.b;
      },
    
      read() {
        this.a = +prompt('a?', 0);
        this.b = +prompt('b?', 0);
      }
    };
    
    calculator.read();
    alert( calculator.sum() );
    alert( calculator.mul() );

    Buka solusi dengan tes di sandbox.

    pentingnya: 2

    Ada sebuah objek layaknya tangga (ladder) yang dapat naik dan turun:

    let ladder = {
      step: 0,
      up() {
        this.step++;
      },
      down() {
        this.step--;
      },
      showStep: function() { // menunjukkan langkah yang sekarang
        alert( this.step );
      }
    };

    Kini, jika kita perlu untuk membuat beberapa panggilan secara berurutan, bisa dilakukan dengan cara seperti ini:

    ladder.up();
    ladder.up();
    ladder.down();
    ladder.showStep(); // 1

    Modifikasi kode up, down dan showStep untuk membuat panggilan-panggilan tersebut dapat dirantaikan satu sama lain, seperti ini:

    ladder.up().up().down().showStep(); // 1

    Pendekatan demikian digunakan secara luas di banyak library JavaScript.

    Buka sandbox dengan tes.

    solusi

    Solusinya adalah untuk mengembalikan objek itu sendiri dari setiap panggilan.

    let ladder = {
      step: 0,
      up() {
        this.step++;
        return this;
      },
      down() {
        this.step--;
        return this;
      },
      showStep() {
        alert( this.step );
        return this;
      }
    };
    
    ladder.up().up().down().up().down().showStep(); // 1

    Kita juga bisa menuliskan sebuah panggilan di setiap baris. Untuk rantai kode yang panjang jadi lebih mudah dibaca seperti ini:

    ladder
      .up()
      .up()
      .down()
      .up()
      .down()
      .showStep(); // 1

    Buka solusi dengan tes di sandbox.

    Peta tutorial

    komentar

    baca ini sebelum berkomentar
    • Jika Anda memiliki saran apa yang harus ditingkatkan - silakan kunjungi kirimkan Github issue atau pull request sebagai gantinya berkomentar.
    • Jika Anda tidak dapat memahami sesuatu dalam artikel harap jelaskan.
    • Untuk menyisipkan beberapa kata kode, gunakan tag <code>, untuk beberapa baris bungkus dengan tag <pre>, untuk lebih dari 10 baris gunakan sandbox (plnkr, jsbin, < a href='http://codepen.io'>codepen)

    Web Proxy Viewer  |  New URL  |  Original Page