this が動的にどう解決されるか、プロトタイプチェーンがどう機能するか、そしてクラスがオブジェクトモデルに実際に何を加えるのかを理解しましょう。
このレッスンを Kodokon で開くthis の値は宣言時ではなく 呼び出し箇所 で決まります。優先度の高い順に4つのルールがあります。new を使った呼び出し、明示的な束縛(call、apply、bind)、メソッドとしての呼び出し(obj.fn())、そして単なる呼び出し(fn())で、これは strict モードでは undefined になります。実務で最もよくあるバグはここから直接生じます。メソッドをそのオブジェクトから取り出すと、暗黙の束縛が壊れるのです。
const user = {
name: "Ada",
greet() {
return "Hello, " + this.name;
},
};
console.log(user.greet()); // "Hello, Ada"
const detached = user.greet;
// detached(); // TypeError: this is undefined
const bound = user.greet.bind(user);
console.log(bound()); // "Hello, Ada"アロー関数は自分自身の this を持ちません。クロージャと同じように、それを囲むスコープから レキシカルに this を捕捉します。そのため、コールバックには理想的ですが、オブジェクトリテラルのメソッドとしては逆効果です。その場合 this は外側のスコープを指してしまいます。内部では、すべてのオブジェクトは自身の プロトタイプチェーン を通じて委譲します。存在しないプロパティは、null に到達するまでリンクをたどって1つずつ探索されます。
function Animal(name) {
this.name = name;
}
Animal.prototype.describe = function () {
return this.name + " is an animal";
};
const dog = new Animal("Rex");
console.log(dog.describe()); // "Rex is an animal"
console.log(Object.getPrototypeOf(dog) ===
Animal.prototype); // true
console.log(dog.hasOwnProperty("describe")); // falseclass 構文はこのモデルを変えるものではなく、読みやすくするものです。クラス本体で宣言されたメソッドは Constructor.prototype に置かれるため 共有 されます。インスタンスフィールド(フィールドとして代入されたアロー関数を含む)は インスタンスごとに 作り直されます。this の束縛は保証されますが、その分メモリコストは倍増します。最後に、#private フィールドは、_underscore の慣習とは違い、エンジンによって強制されるプライバシーを提供します。
class BankAccount {
#balance = 0;
deposit(amount) {
if (amount <= 0) throw new Error("Invalid amount");
this.#balance += amount;
return this;
}
get balance() {
return this.#balance;
}
}
const account = new BankAccount();
account.deposit(50).deposit(25);
console.log(account.balance); // 75fn() の間、this は何ですか?this に関して、アロー関数の特別な点は何ですか?