私の連絡先情報
郵便メール:
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
ES6 のクラスはオブジェクト指向プログラミングの糖衣構文であり、オブジェクトの構造と動作を定義する簡潔な方法を提供します。
JavaScript 言語では、インスタンス オブジェクトを生成する従来の方法はコンストラクターを使用します。以下に例を示します。
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
基本的に、ES6 クラスは、その機能のほとんどが ES5 で実現できます。新しいクラスの記述方法は、オブジェクト プロトタイプの記述方法をより明確にし、オブジェクト指向プログラミングの構文に近づけるだけです。上記のコードは、次のように ES6 クラスを使用して書き換えられます。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
ES6 クラスは、コンストラクターを記述する別の方法とみなすことができます。
class Point {
// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // true
----------------------------------------------------------------------------
class Point {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
// 等同于
Point.prototype = {
constructor() {},
toString() {},
toValue() {},
};
1. 宣言構文: class キーワードを使用してクラスを宣言します。
2. コンストラクター: コンストラクター メソッドを使用してクラス インスタンスを初期化します。
3. インスタンスメソッド: クラス内で定義された共通メソッド。これを使用してインスタンスのプロパティにアクセスします。
4. 静的メソッド: static キーワードを使用して定義され、クラスのインスタンスに依存しません。
5. インスタンスのプロパティ: コンストラクターで初期化するか、フィールド宣言構文を使用します (現在ステージ 3 の提案)。
6. 継承: extends キーワードを使用して実装されます。
7. スーパーキーワード: サブクラスのコンストラクター内で親クラスのコンストラクターまたはメソッドを呼び出します。
8. ゲッターとセッター: get および set を使用して、プロパティのアクセサーを定義します。
9. プライベートプロパティとメソッド: # を使用してプライベート プロパティとメソッドを定義します (現在ステージ 3 の提案)。
1. 基本的なクラスの定義とインスタンス化
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return `Point(${this.x}, ${this.y})`;
}
}
let point = new Point(10, 20);
console.log(point.toString()); // 输出: Point(10, 20)
2. 静的メソッドと静的プロパティ
class MathUtils {
constructor() {
console.log(MyClass.myStaticProp); // 42
}
static add(a, b) {
return a + b;
}
static myStaticProp = 42;
}
console.log(MathUtils.add(1, 2)); // 输出: 3
3. 継承とスーパー
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
area() {
return this.width * this.height;
}
}
class Square extends Rectangle {
constructor(sideLength) {
super(sideLength, sideLength);
}
}
let square = new Square(5);
console.log(square.area()); // 输出: 25
4. ゲッターとセッター
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
get area() {
return this.width * this.height;
}
set width(newWidth) {
if (newWidth > 0) {
this.width = newWidth;
} else {
console.log("Width must be positive.");
}
}
}
let rect = new Rectangle(4, 5);
console.log(rect.area); // 输出: 20
rect.width = -10; // 输出: Width must be positive.
(1)ストリクトモード
内部的には、クラスとモジュールはデフォルトで strict モードになっているため、実行モードを指定するために use strict を使用する必要はありません。コードがクラスまたはモジュールに記述されている限り、厳密モードのみが使用可能です。今後のすべてのコードが実際にはモジュールで実行されることを考慮すると、ES6 では実際に言語全体が厳密モードにアップグレードされます。
(2) プロモーションはありません
ES5 とはまったく異なり、クラスには変数ホイスト (ホイスト) がありません。
new Foo(); // ReferenceError
class Foo {}
//不会报错
//因为 Bar 继承 Foo 的时候, Foo 已经有定义了。
//但是,如果存在 class 的提升,上面代码就会报错,
//因为 class 会被提升到代码头部,而 let 命令是不提升的,
//所以导致 Bar 继承 Foo 的时候, Foo 还没有定义。
{
let Foo = class {};
class Bar extends Foo {
}
}
(3) name 属性
本質的に、ES6 クラスは ES5 コンストラクターのラッパーにすぎないため、name 属性を含め、関数の多くの機能がクラスによって継承されます。
class Point {}
Point.name // "Point"
//name 属性总是返回紧跟在 class 关键字后面的类名。
(4)ジェネレーターメソッド
メソッドの前にアスタリスク (*) が付いている場合は、そのメソッドがジェネレーター関数であることを意味します。
class Foo {
constructor(...args) {
this.args = args;
}
* [Symbol.iterator]() {
for (let arg of this.args) {
yield arg;
}
}
}
for (let x of new Foo('hello', 'world')) {
console.log(x);
}
// hello
// world
//Foo 类的 Symbol.iterator 方法前有一个星号,表示该方法是一个 Generator 函数。
//Symbol.iterator 方法返回一个 Foo 类的默认遍历器, for...of 循环会自动调用这个遍历器。
(5)今回のポイント
クラス メソッドにこれが含まれている場合、デフォルトでクラスのインスタンスを指します。ただし、この方法を単独で使用するとエラーが発生する可能性があるため、十分に注意する必要があります。
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`);
}
print(text) {
console.log(text);
}
}
const logger = new Logger();
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined
これの使用を避け、コンストラクターでこれをバインドします。
class Logger {
constructor() {
this.printName = this.printName.bind(this);
}
// ...
}
これの使用を避け、アロー関数を使用してください。
class Obj {
constructor() {
this.getThis = () => this;
}
}
const myObj = new Obj();
myObj.getThis() === myObj // true
これの使用を避け、プロキシを使用してください
function selfish (target) {
const cache = new WeakMap();
const handler = {
get (target, key) {
const value = Reflect.get(target, key);
if (typeof value !== 'function') {
return value;
}
if (!cache.has(value)) {
cache.set(value, value.bind(target));
}
return cache.get(value);
}
};
const proxy = new Proxy(target, handler);
return proxy;
}
const logger = selfish(new Logger());