Rumah > hujung hadapan web > Soal Jawab bahagian hadapan > Apa yang digunakan untuk melaksanakan warisan dalam es6

Apa yang digunakan untuk melaksanakan warisan dalam es6

青灯夜游
Lepaskan: 2023-02-14 13:56:57
asal
2470 orang telah melayarinya

Dalam es6, kelas dan kata kunci lanjutan digunakan untuk melaksanakan pewarisan. Kata kunci kelas telah diperkenalkan dalam ES6 untuk mengisytiharkan kelas, dan kelas (kelas) boleh diwarisi melalui kata kunci lanjutan, membenarkan subkelas mewarisi sifat dan kaedah kelas induk Sintaksnya ialah "nama kelas induk kelas {.. .} nama subkelas kelas memanjangkan nama kelas induk {...};".

Apa yang digunakan untuk melaksanakan warisan dalam es6

Persekitaran pengendalian tutorial ini: sistem Windows 7, ECMAScript versi 6, komputer Dell G3.

Dalam es6, kata kunci kelas dan kata kunci lanjutan boleh digunakan untuk melaksanakan warisan.

Warisan Kelas ES6

1 Pengenalan

Kelas boleh lulus lanjutan. Kata kunci melaksanakan warisan, membenarkan subkelas mewarisi sifat dan kaedah kelas induk. Ini lebih jelas dan lebih mudah daripada pelaksanaan warisan ES5 dengan mengubah suai rantai prototaip.

//父类
class Point {
 ...
}
//子类
class ColorPoint extends Point {
	constructor(x, y, color) {
		super(x, y);
		this.color = color;
	}
	toString() {
		return this.color + '' + super.toString(); // 调用父类的toString方法
	}
}
Salin selepas log masuk

Dalam kod di atas, kata kunci super muncul dalam kedua-dua kaedah pembina dan kaedah toString Super di sini mewakili pembina kelas induk, yang digunakan untuk mencipta objek contoh baharu induk kelas.

ES6 menetapkan bahawa subkelas mesti memanggil super() dalam kaedah pembina, jika tidak, ralat akan dilaporkan Ini kerana objek subkelas itu sendiri mesti dibentuk melalui pembina kelas induk untuk mendapatkan objek yang sama seperti. kelas induk Sifat dan kaedah contoh yang sama, dan kemudian tambah sifat dan kaedah contoh subkelas itu sendiri.

Mengapakah pembina subkelas mesti memanggil super()?

Ini kerana dalam mekanisme pewarisan ES5, objek contoh subkelas bebas mula-mula dibuat, dan kemudian kaedah kelas induk ditambahkan pada objek ini, iaitu, "contoh pertama , "Wariskan dahulu"; Mekanisme pewarisan ES6 ialah terlebih dahulu menambah atribut dan kaedah kelas induk pada objek kosong, dan kemudian menggunakan objek sebagai contoh subkelas, iaitu, "warisi dahulu, contoh terakhir" .

Ini bermakna setiap kali contoh subkelas baharu dicipta, pembina kelas induk mesti dijalankan dahulu

class Foo {
	constructor() {
		console.log(1);
	}
}

class Bar extends Foo {
	constructor() {
		super();
		console.log(2);
	}
}

const bar = new Bar(); // 1 2
Salin selepas log masuk

Dalam kod di atas, apabila Bar subkelas mencipta tika baharu , ia akan Output 1 dan 2, ini adalah apabila pembina kelas faktor memanggil super(), pembina kelas induk akan dilaksanakan sekali. Kata kunci ini boleh digunakan hanya selepas memanggil super dalam pembina subkelas, jika tidak, ralat akan dilaporkan. Ini kerana pembinaan contoh subkelas mesti terlebih dahulu melengkapkan warisan kelas induk Hanya kaedah super boleh membenarkan contoh subkelas mewarisi kelas induk.

class Point {
	constructor(x, y) {
		this.x = x;
		this.y = y;
	}
}

class ColorPoint extends Point {
	constructor(x, y, color) {
		this.color = color;
		super(x, y);
		this.color = color;
	}
}"
Salin selepas log masuk

Jika subkelas tidak mentakrifkan kaedah pembina, kaedah ini akan ditambah secara lalai, dan super akan dipanggil di dalamnya, maksudnya, mana-mana subkelas mempunyai kaedah pembina tidak kira sama ada ia ditakrifkan secara jelas atau tidak.

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
class ColorPoint extends Point {
}

let cp = new ColorPoint(25, 8);
console.log(cp); //{x: 25, y: 8}

class ColorPoint extends Point {
  constructor(...args) {
    super(...args);
  }
}

let cp = new ColorPoint(25, 8);
console.log(cp); //{x: 25, y: 8}
Salin selepas log masuk

2. Pewarisan harta persendirian dan kaedah persendirian

Semua sifat dan kaedah kelas induk. akan diwarisi oleh subkelas, kecuali untuk yang peribadi Sifat dan kaedah. Subkelas tidak boleh mewarisi sifat peribadi kelas induk, atau sifat persendirian hanya boleh digunakan dalam kelas di mana ia ditentukan.

class Foo {
  #p = 1;
  #m() {
    console.log('hello');
  }
}

class Bar extends Foo {
  constructor() {
    super();
    console.log(this.#p); // 报错
    this.#m(); // 报错
  }
}
Salin selepas log masuk

Dalam contoh di atas, jika Bar subkelas memanggil sifat persendirian atau kaedah persendirian kelas induk Foo, ralat akan dilaporkan.

Jika kelas induk mentakrifkan kaedah baca dan tulis untuk sifat persendirian, subkelas boleh membaca dan menulis sifat persendirian melalui kaedah ini.

class Foo {
  #p = 1;
  getP() {
    return this.#p;
  }
}

class Bar extends Foo {
  constructor() {
    super();
    console.log(this.getP()); // 1
  }
}
Salin selepas log masuk

3. Pewarisan sifat dan kaedah statik

Sifat statik dan kaedah statik kelas induk juga akan diwarisi oleh subkelas.

class A {
  static hello() {
    console.log('hello world');
  }
}

class B extends A {
}

B.hello()  // hello world
Salin selepas log masuk

Dalam kod di atas, hello() ialah kaedah statik kelas A B mewarisi A dan juga mewarisi kaedah statik A.

Perhatikan bahawa sifat statik diwarisi melalui salinan cetek Jika sifat yang diwarisi ialah jenis data primitif, mengendalikan sifat statik yang diwarisi dalam subkelas tidak akan menjejaskan kelas induk, tetapi jika sifat yang diwarisi ialah objek , maka subkelas yang mengubah suai atribut ini akan kagum dengan kelas induk

class C {
	static foo = 100;
}

class D extends C {
	constructor() {
		super();
		D.foo--;
	}
}

const d = new D();
C.foo; // 100
D.foo;  // 99

class A {
	static foo = { n: 100 };
}

class B extends A {
	constructor() {
		super();
		B.foo.n--;
	}
}

const b = new B();
B.foo.n // 99
A.foo.n  // 99
Salin selepas log masuk

4.Object.getPrototypeOf()

Object.getPrototypeOf() kaedah Boleh digunakan untuk mendapatkan kelas induk daripada subkelas.

class Point { /*...*/ }

class ColorPoint extends Point { /*...*/ }

Object.getPrototypeOf(ColorPoint) === Point
// true
Salin selepas log masuk

Oleh itu, anda boleh menggunakan kaedah ini untuk menentukan sama ada kelas mewarisi kelas lain.

5.kata kunci super

Kata kunci super boleh digunakan sama ada sebagai fungsi atau sebagai objek

Bab Dalam satu kes, apabila super dipanggil sebagai fungsi, ia mewakili pembina kelas induk. Fungsi memanggil super adalah untuk membentuk objek subkelas ini, dan meletakkan atribut contoh dan kaedah kelas induk pada objek ini.

class A {
	constructor() {
    console.log(new.target.name);
  }
}

class B extends A {
	constructor() {
		super();
	}
}

new A(); // A
new B(); // B
Salin selepas log masuk

Dalam kes kedua, apabila super digunakan sebagai objek, dalam kaedah biasa, ia menunjuk ke objek prototaip kelas induk, dalam kaedah statik, ia menunjuk ke kelas induk.

class A {
	p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2
  }
}

let b = new B();
Salin selepas log masuk

Dalam kod di atas, super.p() dalam subkelas B menggunakan super sebagai objek Pada masa ini, super dalam objek biasa menghala ke A.prototype, super.p( ) adalah setara kepada A.prototype.p().

Memandangkan super menunjuk ke objek prototaip kelas induk, kaedah atau atribut yang ditakrifkan pada tika kelas induk tidak boleh dipanggil melalui super. Seperti yang ditunjukkan di bawah:

class A {
	constructor() {
		this.p = 2;
	}
}

class B extends A {
	get m() {
		return spuer.p;
	}
}

let b = new B();
b.m // undefined
Salin selepas log masuk

Untuk menyelesaikan masalah ini, anda boleh mentakrifkan atribut pada objek prototaip kelas induk

class A {};
A.prototype.x = 2;

class B extends A {
	constructor() {
		super();
		console.log(super.x);
	}
}

let b = new B();
Salin selepas log masuk

ES6 menetapkan bahawa dalam kaedah biasa subkelas, super Apabila memanggil kaedah kelas induk, ini di dalam kaedah menunjukkan contoh subkelas semasa

class A {
	constructor() {
		this.x = 1;
	}
	print() {
		console.log(this.x);
	}
}

class B extends A {
	constructor() {
		super();
		this.x = 2;
	}
	m() {
		super.print();
	}
}

let b = new B();
b.m(); // 2
Salin selepas log masuk

上面代码中,super.print()调用的是A.prototype.print(),但是此时方法内部的this指向是子类B的实例,所以输出2。

由于this指向的是子类实例,所有如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性

class A {
	constructor() {
		this.x = 1;
	}
}

class B extends A {
	constructor() {
		super();
		this.x = 2;
		super.x = 3;
		console.log(super.x); //undefind
		console.log(this.x); // 3
	}
}
Salin selepas log masuk

上面代码中,super.x赋值为3,这时等同于对this.x赋值为3。而当读取super.x 的时候,读的是A.prototype.x,所以返回undefined

如果super作为对象,用在静态方法之中,这时super将指向父类,而不是父类的原型对象。

class Parent {
	static myMethod(msg) {
		console.log('static', msg);
	}

	myMethod(msg) {
		console.log('instance', msg);
	}
}

class Children extends Parent {
	static myMethod(msg) {
		super.myMthod(msg);
	}

	myMethod(msg) {
    super.myMethod(msg);
  }
}

Child.myMethod(1); // static 1

var child = new Child();
child.myMethod(2); // instance 2
Salin selepas log masuk

上面代码中,super在静态方法之中指向父类,在普通方法之中指向父类的原型对象。

另外,在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例

class A {
	constructor() {
    this.x = 1;
  }
  static print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  static m() {
    super.print();
  }
}

B.x = 3;
B.m() // 3
Salin selepas log masuk

在静态方法m中,super.print指向父类的静态方法,到那时this指向的是类B,而不是B的实例。

【推荐学习:javascript高级教程

Atas ialah kandungan terperinci Apa yang digunakan untuk melaksanakan warisan dalam es6. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan