【ES 6】継承しやすいクラス構文
7811 ワード
他のオブジェクト向けプログラミング言語と同様に、ES 6はclassクラスおよびextend継承構文糖を正式に定義し、静的、派生的、抽象的、反復的、単例などをサポートし、ES 6の新しい特性に基づいて多くの興味深い用法を派生させる.
一、クラスの基本定義
1.コンストラクション関数パッケージデータ が必要 2.プロトタイプにメソッド操作データを追加する 3.Newによるインスタンス の作成
ES 6は、
上記の例では関数宣言は昇格可能であるが、classクラス宣言はletと類似しており、昇格できない. クラス宣言は、厳格なモードで自動的に実行され、「use strict」である. クラスのすべての方法は枚挙にいとまがない.enumerableはfalseである.
二、より柔軟なクラス
一、クラスの基本定義
基本的にすべてのオブジェクト向け言語はクラスのカプセル化と継承をサポートしています.それはクラスとは何ですか.
クラスは、データパッケージ、データ操作、およびメッセージを伝達する関数を含むオブジェクト向けプログラム設計の基礎です.クラスのインスタンスをオブジェクトと呼びます.
ES 5の前に関数によってクラスをシミュレートした実装は以下の通りである.//
function Person(name) {
this.name = name;
}
//
Person.prototype.sayName = function(){
console.log(this.name);
};
// new
var friend = new Person("Jenny");
friend.sayName(); // Jenny
console.log(friend instanceof Person); // true
console.log(friend instanceof Object); // true
要約すると、クラスを定義する考え方は以下の通りです.
//
function Person(name) {
this.name = name;
}
//
Person.prototype.sayName = function(){
console.log(this.name);
};
// new
var friend = new Person("Jenny");
friend.sayName(); // Jenny
console.log(friend instanceof Person); // true
console.log(friend instanceof Object); // true
ES 6は、
class
のキーワードを使用してクラスを定義します.このクラスには、特別なメソッド名[[Construct]]
が構造関数を定義し、newがインスタンスを作成するときに呼び出されるのは[[Construct]]
です.例は次のとおりです./*ES6*/
// let Person = class {
class Person {
//
constructor(name) {
this.name = name;
}
// Person.prototype.sayName
sayName() {
console.log(this.name);
}
}
console.log(typeof Person); // function
console.log(typeof Person.prototype.sayName); // function
let friend = new Person("Jenny");
friend.sayName(); // Jenny
console.log(friend instanceof Person); // true
console.log(friend instanceof Object); // true
上記の例では
class
で定義されたクラスとカスタム関数シミュレーションクラスの機能には違いはないようですが、本質的には大きな違いがあります.二、より柔軟なクラス
クラスは関数と同様に、JavaScriptの一等公民(関数を転送したり、関数から返したり、値を付与したりすることができます)であり、クラスとオブジェクトの字面量にはより多くの類似点があることに気づき、これらの特徴はクラスのより柔軟な定義と使用を拡張することができます.
2.1アクセサ属性を持つ
オブジェクトの属性にはデータ属性とアクセス属性があり、クラスではget
、set
のキーワードでアクセサ属性を定義することもできます.class Person {
constructor(name) {
this.name = name;
}
get value () {
return this.name + this.age
}
set value (num) {
this.age = num
}
}
let friend = new Person("Jenny");
// setter
friend.value = 18
// getter
console.log(friend.value) // Jenny18
2.2計算可能なメンバー名
ES 6オブジェクトの字面量拡張のような計算可能な属性名は、クラス内のメソッドおよびアクセサ属性を含む計算可能なメンバー名を[式]で定義することもできます.let methodName = 'sayName'
class Person {
constructor(name) {
this.name = name;
}
[methodName + 'Default']() {
console.log(this.name);
}
get [methodName]() {
return this.name
}
set [methodName](str) {
this.name = str
}
}
let friend = new Person("Jenny");
//
friend.sayNameDefault(); // Jenny
//
friend.sayName = 'lee'
console.log(friend.sayName) // lee
オブジェクトの新しい特性をさらに熟知したい場合は、「ES 6」オブジェクトの新しい機能と解構賦値を参照してください.
2.3デフォルト反復器の定義
ES 6でよく使用される集合オブジェクト(配列、Set/Map集合)および文字列は反復可能なオブジェクトであり、クラスがこれらの反復可能なオブジェクトの値を表すために使用される場合、デフォルトの反復器を定義するとより便利です.
ES 6は、Symbol.iterator
属性にジェネレータを追加することによって、デフォルトの反復器を定義する.class Person {
constructor(name) {
this.name = name;
}
*[Symbol.iterator]() {
for (let item of this.name){
yield item
}
}
}
var abbrName = new Person(new Set(['j', 'j', 'e', 'e', 'n', 'y', 'y', 'y',]))
for (let x of abbrName) {
console.log(x); // j e n y
}
console.log(...abbrName) // j e n y
デフォルトの反復器を定義したクラスのインスタンスでは、for-of
ループと展開演算子(...)を使用できます.などの反復機能があります.
以上の反復器の内容に困惑する参考:【ES 6】反復器と反復可能オブジェクト
2.4パラメータとしてのクラス
クラスは「一等公民」として、パラメータが入力関数を使用する場合に使用できます.もちろん、関数から返すこともできます.function createClass(className, val) {
return new className(val)
}
let person = createClass(Person,'Jenny')
console.log(person) // Person { name: 'Jenny' }
console.log(typeof person) // object
2.5単一インスタンスの作成
クラス構文を使用して単一のインスタンスを作成するには、newを使用してクラス式をすぐに呼び出します.let singleton = new class {
constructor(name) {
this.name = name;
}
}('Jenny')
console.log(singleton.name) // Jenny
ここで匿名クラス式を作成し、newがクラス式を呼び出し、カッコですぐに実行します.このクラス構文で作成された単一の例は、役割ドメインでクラスの参照を露出しません.
三、クラスの継承
ES 6を振り返る前にどのように継承を実現しますか?一般的な方法は、プロトタイプチェーン、構造関数、および組合せ継承などの方法です.
ES 6のクラスは、よく知られているextends
のキーワードを使用してクラス継承関数を指定し、surpe()
の方法で親クラスの構築関数にアクセスすることができる.
たとえばPersonのクラスを継承します.class Friend extends Person {
constructor(name, phone){
super(name)
this.phone = phone
}
}
let myfriend = new Friend('lee',2233)
console.log(myfriend) // Friend { name: 'lee', phone: 2233 }
FriendはPersonを継承し,用語ではPersonをベースクラス,Friendを派生クラスと呼ぶ.
なお、surpe()
は派生クラスでのみ使用でき、thisの初期化を担当するため、派生クラスがthisを使用する前にsurpe()
を使用する必要があります.
3.1建設対象の継承
ES 6のクラス継承は、組み込みオブジェクト(Array、Set、Mapなど)を継承することができ、継承後はベースクラスのすべての組み込み機能を持つことができる.例:class MyArray extends Array {
}
let arr = new MyArray(1, 2, 3, 4),
subarr = arr.slice(1, 3)
console.log(arr.length) // 4
console.log(arr instanceof MyArray) // true
console.log(arr instanceof Array) // true
console.log(subarr instanceof MyArray) // true
前述の例では、arrは派生クラスMyArrayのインスタンスであるだけでなく、subarrも派生クラスMyArrayのインスタンスであり、組み込みオブジェクト継承の実用的な点は、戻りオブジェクトのタイプを変更することである.
ブラウザエンジンの背後には[Symbol.species]
プロパティは、関数の静的アクセサプロパティを返すために使用され、組み込みオブジェクトが定義されています.[Symbol.species]
属性は、Array、ArrayBuffer、Set、Map、Promise、RegExp、Type arraysである.
3.2式を継承するクラス
現在、extends
はクラスと組み込みオブジェクトを継承できますが、より強力な機能は式からクラスをエクスポートします.
この式の要件は、関数として解析され、[[Construct]]
の属性とプロトタイプを有することができ、例は以下の通りである.function Sup(val) {
this.value = val
}
Sup.prototype.getVal = function () {
return 'hello' + this.value
}
class Derived extends Sup {
constructor(val) {
super(val)
}
}
let der = new Derived('world')
console.log(der) // Derived { value: 'world' }
console.log(der.getVal()) // helloworld
3.3継承できる抽象クラス
ES 6は、new.target
メタ属性判定関数がnewキーワードによって呼び出されたか否かを導入する.クラスの構築関数は、new.target
によってクラスがどのように呼び出されたかを決定することもできる.
抽象クラス(インスタンス化できないクラス)は、new.target
で作成できます.たとえば、次のようになります.class Abstract {
constructor(){
if(new.target === Abstract) {
throw new Error(' ( )')
}
}
}
class Instantiable extends Abstract {
constructor() {
super()
}
}
// let abs = new Abstract() // Error: ( )
let abs = new Instantiable()
console.log(abs instanceof Abstract) // true
Abstract抽象クラスを直接使用してインスタンスを作成することはできませんが、ベースクラスとして他のクラスを派生させることができます.
四、クラスの静的メンバー
ES 6は、static
キーワードを使用して静的メンバーまたはメソッドを宣言する.クラスのメソッドまたはアクセサ属性の前にstatic
を使用できます.唯一の制限は、関数の構築に使用できないことです.
静的メンバーの役割は、一部のクラスメンバーのプライベート化であり、インスタンスにアクセスできないため、クラスに直接アクセスする必要があります.class Person {
constructor(name) {
this.name = name;
}
static create(name) {
return new Person(name);
}
}
let beauty = Person.create("Jenny");
// beauty.create('lee') // TypeError
ベースクラスに静的メンバーがある場合、これらの静的メンバーは派生クラスでも使用できます.
例えば、前例のPersonをベースクラスとしてFriendクラスを派生させ、ベースクラスの静的メソッドcreate()を使用する.class Friend extends Person {
constructor(name){
super(name)
}
}
var friend = Friend.create('lee')
console.log(friend instanceof Person) // true
console.log(friend instanceof Friend) // false
派生クラスは依然としてベースクラスの静的メソッドを使用できることがわかる.
『ES 6を深く理解する』をお勧めします
がんばれ少年!
class Person {
constructor(name) {
this.name = name;
}
get value () {
return this.name + this.age
}
set value (num) {
this.age = num
}
}
let friend = new Person("Jenny");
// setter
friend.value = 18
// getter
console.log(friend.value) // Jenny18
let methodName = 'sayName'
class Person {
constructor(name) {
this.name = name;
}
[methodName + 'Default']() {
console.log(this.name);
}
get [methodName]() {
return this.name
}
set [methodName](str) {
this.name = str
}
}
let friend = new Person("Jenny");
//
friend.sayNameDefault(); // Jenny
//
friend.sayName = 'lee'
console.log(friend.sayName) // lee
class Person {
constructor(name) {
this.name = name;
}
*[Symbol.iterator]() {
for (let item of this.name){
yield item
}
}
}
var abbrName = new Person(new Set(['j', 'j', 'e', 'e', 'n', 'y', 'y', 'y',]))
for (let x of abbrName) {
console.log(x); // j e n y
}
console.log(...abbrName) // j e n y
function createClass(className, val) {
return new className(val)
}
let person = createClass(Person,'Jenny')
console.log(person) // Person { name: 'Jenny' }
console.log(typeof person) // object
let singleton = new class {
constructor(name) {
this.name = name;
}
}('Jenny')
console.log(singleton.name) // Jenny
ES 6を振り返る前にどのように継承を実現しますか?一般的な方法は、プロトタイプチェーン、構造関数、および組合せ継承などの方法です.
ES 6のクラスは、よく知られている
extends
のキーワードを使用してクラス継承関数を指定し、surpe()
の方法で親クラスの構築関数にアクセスすることができる.たとえばPersonのクラスを継承します.
class Friend extends Person {
constructor(name, phone){
super(name)
this.phone = phone
}
}
let myfriend = new Friend('lee',2233)
console.log(myfriend) // Friend { name: 'lee', phone: 2233 }
FriendはPersonを継承し,用語ではPersonをベースクラス,Friendを派生クラスと呼ぶ.
なお、
surpe()
は派生クラスでのみ使用でき、thisの初期化を担当するため、派生クラスがthisを使用する前にsurpe()
を使用する必要があります.3.1建設対象の継承
ES 6のクラス継承は、組み込みオブジェクト(Array、Set、Mapなど)を継承することができ、継承後はベースクラスのすべての組み込み機能を持つことができる.例:
class MyArray extends Array {
}
let arr = new MyArray(1, 2, 3, 4),
subarr = arr.slice(1, 3)
console.log(arr.length) // 4
console.log(arr instanceof MyArray) // true
console.log(arr instanceof Array) // true
console.log(subarr instanceof MyArray) // true
前述の例では、arrは派生クラスMyArrayのインスタンスであるだけでなく、subarrも派生クラスMyArrayのインスタンスであり、組み込みオブジェクト継承の実用的な点は、戻りオブジェクトのタイプを変更することである.
ブラウザエンジンの背後には
[Symbol.species]
プロパティは、関数の静的アクセサプロパティを返すために使用され、組み込みオブジェクトが定義されています.[Symbol.species]
属性は、Array、ArrayBuffer、Set、Map、Promise、RegExp、Type arraysである.3.2式を継承するクラス
現在、
extends
はクラスと組み込みオブジェクトを継承できますが、より強力な機能は式からクラスをエクスポートします.この式の要件は、関数として解析され、
[[Construct]]
の属性とプロトタイプを有することができ、例は以下の通りである.function Sup(val) {
this.value = val
}
Sup.prototype.getVal = function () {
return 'hello' + this.value
}
class Derived extends Sup {
constructor(val) {
super(val)
}
}
let der = new Derived('world')
console.log(der) // Derived { value: 'world' }
console.log(der.getVal()) // helloworld
3.3継承できる抽象クラス
ES 6は、
new.target
メタ属性判定関数がnewキーワードによって呼び出されたか否かを導入する.クラスの構築関数は、new.target
によってクラスがどのように呼び出されたかを決定することもできる.抽象クラス(インスタンス化できないクラス)は、
new.target
で作成できます.たとえば、次のようになります.class Abstract {
constructor(){
if(new.target === Abstract) {
throw new Error(' ( )')
}
}
}
class Instantiable extends Abstract {
constructor() {
super()
}
}
// let abs = new Abstract() // Error: ( )
let abs = new Instantiable()
console.log(abs instanceof Abstract) // true
Abstract抽象クラスを直接使用してインスタンスを作成することはできませんが、ベースクラスとして他のクラスを派生させることができます.
四、クラスの静的メンバー
ES 6は、static
キーワードを使用して静的メンバーまたはメソッドを宣言する.クラスのメソッドまたはアクセサ属性の前にstatic
を使用できます.唯一の制限は、関数の構築に使用できないことです.
静的メンバーの役割は、一部のクラスメンバーのプライベート化であり、インスタンスにアクセスできないため、クラスに直接アクセスする必要があります.class Person {
constructor(name) {
this.name = name;
}
static create(name) {
return new Person(name);
}
}
let beauty = Person.create("Jenny");
// beauty.create('lee') // TypeError
ベースクラスに静的メンバーがある場合、これらの静的メンバーは派生クラスでも使用できます.
例えば、前例のPersonをベースクラスとしてFriendクラスを派生させ、ベースクラスの静的メソッドcreate()を使用する.class Friend extends Person {
constructor(name){
super(name)
}
}
var friend = Friend.create('lee')
console.log(friend instanceof Person) // true
console.log(friend instanceof Friend) // false
派生クラスは依然としてベースクラスの静的メソッドを使用できることがわかる.
『ES 6を深く理解する』をお勧めします
がんばれ少年!
class Person {
constructor(name) {
this.name = name;
}
static create(name) {
return new Person(name);
}
}
let beauty = Person.create("Jenny");
// beauty.create('lee') // TypeError
class Friend extends Person {
constructor(name){
super(name)
}
}
var friend = Friend.create('lee')
console.log(friend instanceof Person) // true
console.log(friend instanceof Friend) // false