ES 6------class基本用法
9831 ワード
まずclassは実はただの文法糖で、ほとんどの機能はES 5で実現することができます.
クラスのすべてのメソッドはクラスのprototypeに定義されます
Objectを使ってもいいです.assignクラスに複数のメソッドを追加
またMyFn.prototype.constructor === MyFn//true
es 5と一致しない点では,クラス内部定義の手法は枚挙にいとまがない.
constructorメソッドはクラスのデフォルトメソッドで、newコマンドでオブジェクトインスタンスを生成するときに自動的に呼び出されるメソッドです.定義が表示されていない場合は、空のconstructorメソッドが自動的に追加され、constructorメソッドはデフォルトでインスタンスオブジェクト(this)を返しますが、別のオブジェクトを返すように指定できます.
es 5と同様に、インスタンスのプロパティは、定義がそれ自体(すなわちthisオブジェクト)に表示されない限り、プロトタイプに定義されます(prototype)
このコードを見て
ここで_proto__構造プロトタイプ(すなわちFoo)を指すので、プロトタイプを修正するには慎重にしなければならないので、使わないほうがいい.
注意クラスとモジュールの内部デフォルトは厳格なモードです
サブクラスはconstructorでsuperメソッドを呼び出さなければなりません.そうしないと、新しいインスタンスが間違って報告されます.これは、サブクラスが独自のthisオブジェクトではなく、親のthisオブジェクトを継承し、加工するためです.
Es 5の継承は実質的にサブクラスのインスタンスオブジェクトthisを作成してから親クラスのメソッドをthisに追加する(Parent.apply(this);
Es 6の継承は実質的に親クラスのインスタンスオブジェクトthisを作成し、その後、子クラスの構造関数によってthisを修飾する.この場合、サブクラスのthisは親インスタンスの加工に基づいているので、サブクラスでキーワードthisを使用するにはsuperを呼び出す必要があります.
1.サブクラスの_proto__構造関数の継承を表す親クラスを指します.
2.サブクラスのprototype._proto__親クラスのprototypeを指し、メソッドの継承を表す.
class A extend Object {}
class A{}は継承が存在しない
このときAはベースクラスとして関数としてFunctionを直接継承する.prototypeですが、Aが呼び出されたときに返されるのはオブジェクトなので、A.prototype._proto__ Objectを指すprototype
class A extend null {}
Object.getPrototypeOf()は、あるクラスが別のクラスを継承しているかどうかを判断するサブクラスから親クラスを取得します.
サブクラスインスタンスの_proto__の_proto__親インスタンスへの__proto__,したがって、親インスタンスの動作は、子クラスで変更できます.
jsの原生構造関数は約9種類あります
Boolean(); Number(); Array(); String(); Object(); Date(); RegExp(); Error(); Function();
以前はこれらの基本的なコンストラクション関数は継承できませんでしたが、例を挙げると、Arrayコンストラクション関数には定義的な属性を制御する内部属性[[DefineOwnProperty]]があり、この内部属性はサブクラスで取得できないため、サブクラスlength属性の動作が正常ではありません.
でもes 6は
Es 6のgetterとsetterは、属性のdescriptorオブジェクトに定義されています.
Objectを使ってもいいです.getOwnPropertyDescriptor()
1つのメソッドの前にstaticキーワードを付けると、このメソッドはインスタンスによって継承されませんが、サブクラスは親の静的メソッドを継承し、静的メソッドはsuperから呼び出すこともできます.
静的属性とは、インスタンスオブジェクト(this)に定義された属性ではなく、class自体の属性を指し、es 6はclassが静的メソッドのみ静的属性を持たないことを明確に規定する
どちらの方法も無効です.間違いはありませんが.
newコマンドで呼び出されたコンストラクション関数を返します.コンストラクション関数がnewコマンドで呼び出されていない場合、undefinedが返されます.
次の2つの方法は、コンストラクション関数がnewでのみ呼び出されることを保証するために使用されます.
class内部呼び出しnew.targetは現在のclassを返し、サブクラスが親クラスを継承するときnew.targetはサブクラスを返すので,この特徴を利用して独立して使用できない,継承して使用するしかないクラスを書くことができる.
注意関数の外部でnewを呼び出す.targetはエラーを報告します
Mixinモードとは、複数のクラスのインタフェースを別のクラスに混入することを意味する
クラスのすべてのメソッドはクラスのprototypeに定義されます
class MyFn {}
let a = new MyFn();
a.constructor === MyFn.prototype.constructor // ture
Objectを使ってもいいです.assignクラスに複数のメソッドを追加
Object.assign(MyFn.ptototype, {
toString() {},
toValue() {}
})
またMyFn.prototype.constructor === MyFn//true
es 5と一致しない点では,クラス内部定義の手法は枚挙にいとまがない.
Object.keys(MyFn.prototype) // []
Object.getOwnPropertyNames(MyFn.prototype) // ['toString', 'toValue']
constructorメソッド
constructorメソッドはクラスのデフォルトメソッドで、newコマンドでオブジェクトインスタンスを生成するときに自動的に呼び出されるメソッドです.定義が表示されていない場合は、空のconstructorメソッドが自動的に追加され、constructorメソッドはデフォルトでインスタンスオブジェクト(this)を返しますが、別のオブジェクトを返すように指定できます.
class Foo {
constructor () {
return Object.create(null);
}
}
new Foo() instanceof Foo // false
es 5と同様に、インスタンスのプロパティは、定義がそれ自体(すなわちthisオブジェクト)に表示されない限り、プロトタイプに定義されます(prototype)
このコードを見て
var a = new Foo();
var b = new Foo();
a.__proto__.newProperty = function () { console.log("Attention !!!") }
b.newProperty(); // "Attention !!!"
ここで_proto__構造プロトタイプ(すなわちFoo)を指すので、プロトタイプを修正するには慎重にしなければならないので、使わないほうがいい.
Class式を使用すると、即時関数形式を書くことができます。
var foo = class {
constructor (val) {
this.value = val;
}
printVal () {
cosole.log(this.value)
}
}("money")
class変数の昇格は存在しません
new Foo(); // ReferenceError
class Foo {}
注意クラスとモジュールの内部デフォルトは厳格なモードです
classの継承
サブクラスはconstructorでsuperメソッドを呼び出さなければなりません.そうしないと、新しいインスタンスが間違って報告されます.これは、サブクラスが独自のthisオブジェクトではなく、親のthisオブジェクトを継承し、加工するためです.
Es 5の継承は実質的にサブクラスのインスタンスオブジェクトthisを作成してから親クラスのメソッドをthisに追加する(Parent.apply(this);
Es 6の継承は実質的に親クラスのインスタンスオブジェクトthisを作成し、その後、子クラスの構造関数によってthisを修飾する.この場合、サブクラスのthisは親インスタンスの加工に基づいているので、サブクラスでキーワードthisを使用するにはsuperを呼び出す必要があります.
クラスのprototypeと_proto__ ツールバーの
1.サブクラスの_proto__構造関数の継承を表す親クラスを指します.
2.サブクラスのprototype._proto__親クラスのprototypeを指し、メソッドの継承を表す.
class A {};
class B {};
Object.setPrototypeOf(B.prototype, A.prototype);
Object.setPrototypeOf(B, A);
Object.setPrototypeOf = function (obj, proto) {
obj.__proto__ = proto;
return obj;
}
受け継がれたいくつかの状況
class A extend Object {}
A.__proto__ === Object // true
A.prototype.__proto__ === Object.prototype // true
class A{}は継承が存在しない
A.__proto__ === Function.prototype // true
A.prototype.__proto__ === Object.prototype // true
このときAはベースクラスとして関数としてFunctionを直接継承する.prototypeですが、Aが呼び出されたときに返されるのはオブジェクトなので、A.prototype._proto__ Objectを指すprototype
class A extend null {}
A.__proto__ === Function.prototype // true
A.prototype.__proto__ === undefined // true
Object.getPrototypeOf()は、あるクラスが別のクラスを継承しているかどうかを判断するサブクラスから親クラスを取得します.
サブクラスインスタンスの_proto__の_proto__親インスタンスへの__proto__,したがって、親インスタンスの動作は、子クラスで変更できます.
class Foo {}
class Bar extends Foo {}
var a1 = new Foo();
var a2 = new Bar();
a2.__proto__ === a1.__proto__; // false
a2.__proto__.__proto__ === a1.__proto__; // true
a2.__proto__.__proto__.printName = function () {
console.log("this is a2")
}
a1.printName() // "this is a2"
アコースティックコンストラクション関数の継承
jsの原生構造関数は約9種類あります
Boolean(); Number(); Array(); String(); Object(); Date(); RegExp(); Error(); Function();
以前はこれらの基本的なコンストラクション関数は継承できませんでしたが、例を挙げると、Arrayコンストラクション関数には定義的な属性を制御する内部属性[[DefineOwnProperty]]があり、この内部属性はサブクラスで取得できないため、サブクラスlength属性の動作が正常ではありません.
でもes 6は
class MyArray extends Array {
constructor (...arg) {
super(...arg);
}
}
var myArray = new MyArray();
classのgetterとsetter
Es 6のgetterとsetterは、属性のdescriptorオブジェクトに定義されています.
Objectを使ってもいいです.getOwnPropertyDescriptor()
class A {
constructor () { *** }
get oneProp () { *** }
set oneProp () { *** }
}
var oDescriptor = Object.getOwnPropertyDescriptor(A , "oneProp");
"get" in oDescriptor; //true
"set" in oDescriptor; // true
classの静的方法
1つのメソッドの前にstaticキーワードを付けると、このメソッドはインスタンスによって継承されませんが、サブクラスは親の静的メソッドを継承し、静的メソッドはsuperから呼び出すこともできます.
classの静的プロパティ
静的属性とは、インスタンスオブジェクト(this)に定義された属性ではなく、class自体の属性を指し、es 6はclassが静的メソッドのみ静的属性を持たないことを明確に規定する
class Foo {
prop: 1
static prop : 1
}
Foo.prop // undefined
どちらの方法も無効です.間違いはありませんが.
new.targetプロパティ
newコマンドで呼び出されたコンストラクション関数を返します.コンストラクション関数がnewコマンドで呼び出されていない場合、undefinedが返されます.
次の2つの方法は、コンストラクション関数がnewでのみ呼び出されることを保証するために使用されます.
1.
function Person(name) {
if(new.target !== undefined) {
this.name = name;
}else {
throw new Error (" new ")
}
}
2.
function Person (name) {
if(new.target === Person) {
this.name = name;
}else {
throw new Error (" new ")
}
}
class内部呼び出しnew.targetは現在のclassを返し、サブクラスが親クラスを継承するときnew.targetはサブクラスを返すので,この特徴を利用して独立して使用できない,継承して使用するしかないクラスを書くことができる.
class Shape {
constructor () {
if(new.target === Shape) {
throw new Error (" new ")
}
}
}
class Rectangle extends Shape {
constructor () {
super()
***
}
}
var x = new Shape() //
var x = Rectangle() //
注意関数の外部でnewを呼び出す.targetはエラーを報告します
Mixinモードの実装
Mixinモードとは、複数のクラスのインタフェースを別のクラスに混入することを意味する
function mix(...mixins) {
class Mix {}
for (let mixin of minins) {
copyProperties(Mix, mixin);
copyProperties(Mix.prototype, mixin.prototype);
}
return Mix;
}
function copyProperties(target, source) {
for( let key of Reflect.ownKeys(source)) {
if( key !== "constuctor" &&
key !== "prototype" &&
key !== "name") {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperties(target, key, desc);
}
}
}
class DistributedEdit extends mix(Loggable, Serializable) {
// ..
}