[TIL#29]このバインディング
20149 ワード
JavaScriptを学ぶ際には、必ず知っておくべき概念でこの点を言及することがよくあります.ただし、JavaScriptのthisは他の言語の動作とは少し異なり、JavaScriptの関数の呼び出し方法によっては他のオブジェクトがバインドされるため、最初の表示では難しいと考えられる場合があります.しかし、これは必須の概念であり、私たちは必ず理解しなければならない.🏃♂️
(本文は内部JavaScript一書を読み、学習し、整理した)
これは何ですか.
このコンテキストバインドについて議論する前に、このコンテキストバインドが何であるかを理解してください.
thisは、コンストラクション関数またはメソッドでオブジェクトを指すときに使用されるキーワードです.新規オブジェクトに作成者の属性を入れる場合 オブジェクトにアクセスするプロパティ 1.オブジェクトのメソッドを呼び出すときにこのメソッドをバインドする
メソッドとは、オブジェクトのプロパティが関数である場合、この関数をメソッドと呼びます.
このメソッドを呼び出すと、メソッド内で使用されるthisがメソッドを呼び出すオブジェクトにバインドされます.
サンプルコード
前述したように、メソッドは、メソッドを呼び出すオブジェクトにバインドされる.
2.関数の呼び出し時にこの関数をバインドする
関数を呼び出すと、関数の内部コードで使用されるthisがグローバルオブジェクトにバインドされます.
(ブラウザでJavaScriptを実行すると、グローバルオブジェクトはwindowオブジェクトになります)
燒グローバルオブジェクトとは、常にグローバル範囲内に存在するオブジェクトです.MDN
サンプルコード 3.コンストラクション関数の呼び出し時にこの関数をバインドする
JavaScriptでオブジェクトを作成する方法は、
コンストラクション関数を呼び出すと、コンストラクション関数コードの内部でthisはコンストラクション関数生成のオブジェクトにバインドされます.この点を理解するには、まず、コンストラクション関数が呼び出されたときの動作を理解します.
ジルコニアジェネレータ関数の動作
1.空のオブジェクトを作成してバインドする
ジェネレータ関数コードが実行される前に、空のオブジェクトが作成され、このオブジェクトにバインドされます.したがって、後でコンストラクション関数のコード内で使用されるthisは、この空のオブジェクトを指します.
(厳密には、オブジェクトは空のオブジェクトではなく、そのプロトタイププロファイルが指すオブジェクトを独自のプロトタイププロファイルに設定します)
2.ここからPropertyを作成する
関数コードの内部では、thisを使用して前に作成した空のオブジェクトにプロパティやメソッドなどを動的に作成できます.
3.作成したオブジェクトを返します
文が返されない場合は、このバインドで新しく作成されたオブジェクトが返されます.戻り文が個別に存在し、他のオブジェクトが返される場合、返されるオブジェクトはthisではありません.
オブジェクト文字vsコンストラクション関数
4.apply、callを使用してこの項目を明示的にバインド
前述したthisバインドは、関数呼び出しが発生したときに状況に応じて自動的にバインドできます.今回は、apply()メソッドとcall()メソッドを可能にするために、特定のオブジェクトに明示的にバインドする方法について説明します.
(call()メソッドはapply()メソッドと機能は同じですが、パラメータのフォーマットが異なるだけです)
呼び出し方式から見ると、呼び出しapply()メソッドの主体は関数であり、apply()メソッドも特定のオブジェクトにバインドされ、その本質的な機能は関数呼び出しである.
最初のパラメータ
2番目のパラメータ
要するに、apply()メソッドは、その関数を呼び出すパラメータとして
サンプルコード
call()メソッドはapply()メソッドと同じ機能を持つが,apply()で2番目のパラメータに渡される配列形式をそれぞれ1つのパラメータに渡す.上記の例をcall()メソッドに変更すると、次のようになります.
❗ES 6に新しく追加されたArrayでもあります.「from()」メソッドを使用して、類似配列オブジェクトまたは重複可能オブジェクトをより浅い位置にコピーして、新しいオブジェクトを作成します.MDN
5.イベントハンドラを呼び出すときにバインド
イベントハンドラでは、イベントを受信するHTML要素にバインドされます.
サンプルコード
上記の一般関数を呼び出す場合のthisのバインドは、矢印関数を呼び出す場合のthisのバインドと大きく異なります.
グローバルオブジェクトにバインドされた通常の関数のthisとは異なり、矢印関数は最近のscopeに存在するthisバインドに従います.
サンプルコード
矢印関数を使用して同じコードを記述する場合は、次のようになります.
矢印関数の注意事項
これらの特性のため、オブジェクトの方法を矢印関数として使用するのは適切ではないことを知っておく必要があります!!
参考資料
参考資料
(本文は内部JavaScript一書を読み、学習し、整理した)
これは何ですか.
このコンテキストバインドについて議論する前に、このコンテキストバインドが何であるかを理解してください.
thisは、コンストラクション関数またはメソッドでオブジェクトを指すときに使用されるキーワードです.
メソッドとは、オブジェクトのプロパティが関数である場合、この関数をメソッドと呼びます.
このメソッドを呼び出すと、メソッド内で使用されるthisがメソッドを呼び出すオブジェクトにバインドされます.
サンプルコード
var firstObject = {
name: 'first',
sayName: function () {
console.log(this.name);
}
};
var secondObject = {
name: 'second'
};
secondObject.sayName = firstObject.sayName;
// sayName() 메서드 호출
firstObject.sayName(); // first
secondObject.sayName(); // second
firstObject
およびsecondObject
オブジェクトは、name
propertyおよびsayName()
メソッドを有する.前述したように、メソッドは、メソッドを呼び出すオブジェクトにバインドされる.
firstObject.sayName();
では、firstObject
オブジェクト呼び出しsayName()
メソッドであるため、ここではfirstObjectオブジェクトである.secondObject.sayName();
では、secondObject
オブジェクト呼び出しsayName()
メソッドであるため、ここではsecondObjectオブジェクトである.2.関数の呼び出し時にこの関数をバインドする
関数を呼び出すと、関数の内部コードで使用されるthisがグローバルオブジェクトにバインドされます.
(ブラウザでJavaScriptを実行すると、グローバルオブジェクトはwindowオブジェクトになります)
燒グローバルオブジェクトとは、常にグローバル範囲内に存在するオブジェクトです.MDN
サンプルコード
var test = "This is test"; // 전역변수 선언
console.log(window.test); // This is test
var sayFoo = function () {
console.log(this.test); // 결국 window.test를 의미한다
};
sayFoo(); // This is test
test
グローバル変数window
グローバルオブジェクトとしてのpropertyアクセスsayFoo()
関数で使用されるthisはグローバルオブジェクトにバインドされるため、sayFoo()
が呼び出されると、thisはグローバルオブジェクトwindow
にバインドされる.JavaScriptでオブジェクトを作成する方法は、
1. 객체 리터럴 방식
、2. 생성자 함수 이용
の2つです.コンストラクション関数を呼び出すと、コンストラクション関数コードの内部でthisはコンストラクション関数生成のオブジェクトにバインドされます.この点を理解するには、まず、コンストラクション関数が呼び出されたときの動作を理解します.
ジルコニアジェネレータ関数の動作
new
演算子を使用してJavaScript関数をコンストラクション関数として呼び出し、以下の手順で操作します.1.空のオブジェクトを作成してバインドする
ジェネレータ関数コードが実行される前に、空のオブジェクトが作成され、このオブジェクトにバインドされます.したがって、後でコンストラクション関数のコード内で使用されるthisは、この空のオブジェクトを指します.
(厳密には、オブジェクトは空のオブジェクトではなく、そのプロトタイププロファイルが指すオブジェクトを独自のプロトタイププロファイルに設定します)
2.ここからPropertyを作成する
関数コードの内部では、thisを使用して前に作成した空のオブジェクトにプロパティやメソッドなどを動的に作成できます.
3.作成したオブジェクトを返します
文が返されない場合は、このバインドで新しく作成されたオブジェクトが返されます.戻り文が個別に存在し、他のオブジェクトが返される場合、返されるオブジェクトはthisではありません.
オブジェクト文字vsコンストラクション関数
// 객체 리터럴 방식으로 객체 생성
var me = {
name: 'minkyoung',
age: 26
};
// 생성자 함수로 객체 생성
function Person(name, age) {
this.name = name;
this.age = age;
}
// 같은 형태의 객체를 재생성할 수 있다
var test = new Person('test', 20);
var foo = new Person('foo',22);
console.log(test.name); // test
console.log(foo.name); // foo
new
がない場合にコンストラクション関数が呼び出されると、通常の関数が呼び出されます.この場合、この関数はwindowグローバルオブジェクトにバインドされます.4.apply、callを使用してこの項目を明示的にバインド
前述したthisバインドは、関数呼び出しが発生したときに状況に応じて自動的にバインドできます.今回は、apply()メソッドとcall()メソッドを可能にするために、特定のオブジェクトに明示的にバインドする方法について説明します.
(call()メソッドはapply()メソッドと機能は同じですが、パラメータのフォーマットが異なるだけです)
function.apply(thisArg, argArray)
と同じフォーマットでapply()メソッドを呼び出すことができます.呼び出し方式から見ると、呼び出しapply()メソッドの主体は関数であり、apply()メソッドも特定のオブジェクトにバインドされ、その本質的な機能は関数呼び出しである.
最初のパラメータ
thisArg
は、関数にバインドするthisのオブジェクトを指します.2番目のパラメータ
argArray
は、関数を呼び出すときに渡されるパラメータの配列です.要するに、apply()メソッドは、その関数を呼び出すパラメータとして
argArray
配列を使用し、この関数の内部で使用されるthisはthisArg
オブジェクトにバインドされて関数を呼び出す.サンプルコード
// 생성자 함수
function Person(name, age) {
this.name = name;
this.age = age;
}
// me 빈 객체 생성
var me = {};
Person.apply(me, ['minkyoung',26]);
上のme
オブジェクトは、文字で作成された空のオブジェクトであり、apply()メソッドを使用してPerson('minkyoung', 26)
関数を呼び出し、me
オブジェクトに明示的にバインドします.call()メソッドはapply()メソッドと同じ機能を持つが,apply()で2番目のパラメータに渡される配列形式をそれぞれ1つのパラメータに渡す.上記の例をcall()メソッドに変更すると、次のようになります.
Person.call(me, 'minkyong', 26);
apply()メソッド、call()メソッドは、主に類似配列オブジェクトに配列メソッドを書き込むために使用されます.❗ES 6に新しく追加されたArrayでもあります.「from()」メソッドを使用して、類似配列オブジェクトまたは重複可能オブジェクトをより浅い位置にコピーして、新しいオブジェクトを作成します.MDN
5.イベントハンドラを呼び出すときにバインド
イベントハンドラでは、イベントを受信するHTML要素にバインドされます.
サンプルコード
var btn = document.querySelector("#btn");
btn.addEventListener('click', function () {
console.log(this); // #btn
};
6.矢印関数の呼び出し時にこの関数をバインドする上記の一般関数を呼び出す場合のthisのバインドは、矢印関数を呼び出す場合のthisのバインドと大きく異なります.
グローバルオブジェクトにバインドされた通常の関数のthisとは異なり、矢印関数は最近のscopeに存在するthisバインドに従います.
サンプルコード
const minkyoung = {
name: 'minkyoung',
happy: true,
printHobby: function() {
const game = "game";
let hobby = game;
function checkHappy() {
if(this.happy) hobby += " is funny";
return hobby;
}
return `minkyoung's hobby : ${checkHappy()}`;
}
}
minkyoung.printHobby(); // minkyoung's hobby : game
このコードでは、this
がwindowを指しているため、happy: true
が理解できず、予想通りに出力できません.矢印関数を使用して同じコードを記述する場合は、次のようになります.
const minkyoung = {
name: 'minkyoung',
happy: true,
printHobby: function() {
const game = "game";
let hobby = game;
let checkHappy = () => {
if(this.happy) hobby += " is funny";
return hobby;
}
return `minkyoung's hobby : ${checkHappy()}`;
}
}
minkyoung.printHobby(); // minkyoung's hobby : game is funny
このコードは矢印関数を使用するため、printHobby
の手順に従ってminkyoung
オブジェクトをバインドします.矢印関数の注意事項
const person = {
name: "minkyoung",
print: () => console.log(this.name)
};
person.pirnt(); // 에러 발생
これは、メソッドを呼び出すオブジェクトではなく親コンテキストのグローバルオブジェクトをバインドしているため、エラーを引き起こします.これらの特性のため、オブジェクトの方法を矢印関数として使用するのは適切ではないことを知っておく必要があります!!
参考資料
参考資料
Reference
この問題について([TIL#29]このバインディング), 我々は、より多くの情報をここで見つけました https://velog.io/@jminkyoung/TIL-29-this의-바인딩テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol