第22章
26877 ワード
この欄
まず、コンストラクション関数によってインスタンスを作成する例を見てみましょう.
function Circle(radius) {
// 이 시점에는 생성자 함수 자신이 생성할 인스턴스를 가리키는 식별자를 알 수 없다.
???.radius = radius;
}
const circle = new Circle(5);
コンストラクション関数を定義するときにインスタンスが作成されていないため、コンストラクション関数は作成するインスタンスを指す識別子を認識できません.このためjavascriptには、this
という特殊な識別子が提供され、自分が属するオブジェクトまたは自分が作成するインスタンスを指すことができます.this
はjavascriptエンジンによって暗黙的に生成され、関数を呼び出すと暗黙的に関数内部に渡されます.その後、this
は、関数内部で領域変数のように使用することができる.this
は、自分が属するオブジェクトまたは作成するインスタンスを指す自己参照変数(self-reference変数)です.関数呼び出しとバインド
this
が指す値を表すこのバインディングは、関数呼び出し方式によって動的に決定される.関数は、さまざまな方法で呼び出すことができます.
呼び出し
this 바인딩
を見てみましょう.一般関数の呼び出し
デフォルトでは、
this
はグローバルオブジェクトをバインドします.// 전역 함수
function foo() {
console.log("foo's this: ", this); // window
// 중첩 함수
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
グローバル関数だけでなく、ネストされた関数も通常の関数として呼び出されると、関数内部のthis
がグローバルオブジェクトをバインドします.function foo() {
// strict mode 적용
'use strict';
console.log("foo's this: ", this); // undefined
function bar() {
console.log("bar's this: ", this); // undefined
}
bar();
}
foo();
しかし、strict mode
を適用する一般的な関数の内部のthis
はundefinedにバインドされる.this
は、オブジェクトを参照するためのPropertyまたはメソッドの自己参照変数であるため、オブジェクトを作成しない通常の関数では意味がありません.コールバック関数も通常の関数として呼び出されると、グローバルオブジェクトがバインドされます.
// 전역 변수
var value = 1;
const obj = {
value: 100,
foo() {
console.log("foo's this: ", this); // {value: 100, foo: f}
// 콜백 함수
setTimeout(function() {
console.log("callback's this: this", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();
上記の例では、ドメイン内でsetTimeout
関数に渡されるコールバック関数のthis
にグローバルオブジェクトがバインドされる.したがって、this.value
は、obj
オブジェクトのvalue
ではなく、グローバルオブジェクトのwindow.value
を参照する.コールバック関数の
this
をobj
オブジェクトのvalue
とどのようにマッチングしますか?📙 1.このバインディングを割り当てる
var value = 1;
const obj = {
value: 100,
foo() {
const that = this;
console.log(that); // {value: 100, foo: f}
setTimeout(function() {
console.log(that.value); // 100
}, 100);
}
};
obj.foo();
このバインディングが変数that
に割り当てられる場合、コールバック関数の内部ではthis
ではなくthat
を参照することができる.📙 2. Function.prototype.bind()
さらにjavascriptは、
this
を明示的にバインドする機能も有する.prototype.bindメソッドを提供します.var value = 1;
const obj = {
value: 100,
foo() {
setTimeout(function() {
console.log(this.value); // 100
}.bind(this), 100);
}
};
obj.foo();
📙 3.矢印関数矢印関数を使用して、
this
バインドを一致させることができます.var value = 1;
const obj = {
value: 100,
foo() {
setTimeout(() => console.log(this.value), 100); // 100
}
};
obj.foo();
メソッド呼び出し
メソッド内の
this
は、メソッドのオブジェクトではなく呼び出しメソッドにバインドされます.const person = {
name: 'Lee',
getName() {
return this.name;
}
};
console.log(person.getName()); // Lee
方法はプログラムにバインドされた関数です.person
オブジェクトのgetName
パーセントで表される関数オブジェクトは、person
オブジェクトに含まれるのではなく、独立して存在する独立したオブジェクトです.getName Propertyは、関数オブジェクトのみを指します.したがって、getNameメソッドは、getNameプロパティが指す関数オブジェクトであり、別のオブジェクトのプロパティに割り当てられ、別のオブジェクトのメソッドであっても、通常の変数に割り当てられ、通常の関数として呼び出されます.
const person = {
name: 'Lee',
getName() {
return this.name;
}
};
const anotherPerson = {
name: 'Kim'
};
// anotherPerson 객체에 할당
anotherPerson.getName = person.getName;
console.log(anotherPerson.getName()); // Kim
// 변수에 할당
const getName = person.getName;
console.log(getName()); // ''
getName
メソッドをanotherPerson
オブジェクトのメソッドとして指定し、anotherPerson
オブジェクトのgetName
メソッドを呼び出し、結果として「Lee」ではなく「Kim」が表示されます.また、一般関数によって呼び出される
getName
関数内部のthis.name
は、ブラウザ環境においてwindow.name
と同じである.ブラウザ環境では、window.name
はブラウザウィンドウの名前を表し、デフォルト値は''
です.このように、メソッド内部の
this
は、propertyとしてメソッドを指すオブジェクトとは無関係に、呼び出しメソッドのオブジェクトにバインドされる.コンストラクタの呼び出し
コンストラクション関数内部の
this
では、コンストラクション関数によって生成されるインスタンスをバインドします.function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
// 생성자 함수로 호출
const circle1 = new Circle(5);
console.log(circle1.getDiameter()); // 10
// 일반 함수로 호출
const circle2 = Circle(10);
console.log(circle2); // undefined
第17章構築関数で見たように、new
演算子とともに呼び出されると、この関数はコンストラクション関数として動作し、new
演算子とともにコンストラクション関数を呼び出さなければ、通常の関数として動作する.通常の関数を使用する場合、Circle
関数には文が返されないため、デフォルトでは定義されていません.apply/call/bind()呼び出し
apply
、call
、bind
の方法はFunction.prototype
の方法であるので、これらの方法はすべての関数によって継承されて使用することができる.apply
、call
メソッドは、使用するオブジェクトを受信し、関数を呼び出す.function getThisBinding() {
return this;
}
// this로 사용할 객체
const thisArg = { a: 1 };
console.log(getThisBinding()); // window
console.log(getThisBinding.apply(thisArg)); // { a: 1 }
console.log(getThisBinding.call(thisArg)); // { a: 1 }
this
関数を呼び出し、パラメータとして渡されたオブジェクトをgetThisBinding
関数のgetThisBinding
にバインドします.これとは異なり、
this
メソッドは関数を呼び出さず、bind
として使用されるオブジェクトのみを渡す.function getThisBinding() {
return this;
}
// this로 사용할 객체
const thisArg = { a: 1 };
console.log(getThisBinding.bind(thisArg)); // getThisBinding
console.log(getThisBinding.bind(thisArg)()); // { a: 1 }
this
メソッドは、bind
として使用するオブジェクトのみを関数に渡すため、関数を呼び出さずに明示的に呼び出さなければならない.これまで,関数呼び出し方式によるthisバインドの決定について議論した.以下に整理します!
関数呼び出しメソッドこのバインド汎用関数呼び出しグローバルオブジェクトメソッド呼び出しのオブジェクトジェネレータ関数番号生成構造関数は、インスタンスアプリケーション/call/bind()呼び出しアプリケーション/call/bind()メソッドのオブジェクトをパラメータとしてパラメータに渡す
Reference
この問題について(第22章), 我々は、より多くの情報をここで見つけました https://velog.io/@niyu/22장-thisテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol