kembali ke pelajaran

_Class extends Object?_

pentingnya: 3

Seperti yang kita ketahui, semua objek biasanya diwarisi dari Object.prototype dan mendapatkan akses ke metode objek “generic” seperti hasOwnProperty dll.

Misalnya:

class Rabbit {
  constructor(name) {
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

// metode hasOwnProperty dari Object.prototype
alert( rabbit.hasOwnProperty('name') ); // true

Tapi jika kita mengejanya secara eksplisit seperti "class Rabbit extends Object", maka hasilnya akan berbeda dari "class Rabbit"?

Apa perbedaannya?

Berikut contoh kodenya (tidak berhasil – mengapa? memperbaikinya?):

class Rabbit extends Object {
  constructor(name) {
    this.name = name;
  }
}

let rabbit = new Rabbit('Rab');

alert(rabbit.hasOwnProperty('name')); // Error

Pertama, mari kita lihat mengapa kode terakhir tidak berfungsi.

Alasannya menjadi jelas jika kita mencoba menjalankannya. Konstruktor kelas yang mewarisi harus memanggil super(). Jika tidak, "this" tidak akan “defined”.

Jadi, inilah perbaikannya:

class Rabbit extends Object {
  constructor(name) {
    super(); // perlu memanggil konstruktor induk saat mewarisi
    this.name = name;
  }
}

let rabbit = new Rabbit("Rab");

alert( rabbit.hasOwnProperty('name') ); // true

Tapi itu belum semuanya.

Bahkan setelah perbaikan, masih ada perbedaan penting dalam "class Rabbit extends Object" versus class Rabbit.

Seperti yang kita tahu, sintaks “extends” menyiapkan dua prototipe:

  1. Antara "prototype" dari fungsi konstruktor (untuk metode).
  2. Antara konstruktor berfungsi sendiri (untuk metode statis).

Dalam kasus kita, untuk class Rabbit extends Object itu berarti:

class Rabbit extends Object {}

alert(Rabbit.prototype.__proto__ === Object.prototype); // (1) true
alert(Rabbit.__proto__ === Object); // (2) true

Jadi Rabbit sekarang menyediakan akses ke metode statis Object melalui Rabbit, seperti ini:

class Rabbit extends Object {}

// biasanya kita sebut Object.getOwnPropertyNames
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // a,b

Tetapi jika kita tidak punya extends Object, lalu Rabbit.__proto__ tidak diatur ke Object.

Berikut demo nya:

class Rabbit {}

alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true
alert( Rabbit.__proto__ === Object ); // (2) false (!)
alert( Rabbit.__proto__ === Function.prototype ); // sebagai fungsi apa pun secara default

// error, tidak ada fungsi seperti itu di Rabbit
alert ( Rabbit.getOwnPropertyNames({a: 1, b: 2})); // Error

Jadi Rabbit tidak menyediakan akses ke metode statis Object dalam hal itu.

Ngomong-ngomong, Function.prototype mempunyai fungsi metode “generic”, seperti call, bind dll. Mereka terakhir tersedia dalam kedua kasus, karena untuk konstruktor Object bawaan, Object.__proto__ === Function.prototype.

Berikut gambarnya:

Jadi, sederhananya, ada dua perbedaan:

class Rabbit class Rabbit extends Object
needs to call super() in constructor
Rabbit.__proto__ === Function.prototype Rabbit.__proto__ === Object