this
15835 ワード
call,applyメソッド
カッコを簡単に開いたり閉じたりするほか、メソッドを使用して関数を実行することもできます.function foo() {
return 'bar';
}
foo()
foo.call()
foo.apply()
.call, .apply呼び出しは、この値を明確に指定するために使用されます.
最初のパラメータは常にこの値です.
applyを使用して配列係数を解放する例
// null을 this로 지정한다. Math는 생성자가 아니므로 this를 지정할 필요가 없다.
Math.max.apply(null, [5, 4, 1, 6, 2]) // 6
// spread operator의 도입으로 굳이 apply를 이용할 필요가 없어졌다.
Math.max(...[5, 4, 1, 6, 2]) // 6
プロトタイプによる実行例
// '피', '땀', '눈물'을 this로 지정한다.
''.split.call('피, 땀, 눈물', ',')
// 다음과 정확히 동일한 결과를 리턴한다.
'피, 땀, 눈물'.split(',')
実用的な例
let allDivs = document.querySelectAll('div') // Node.js라는 유사 배열이다.
// allDivs를 this로 지정한다.
[].map.call(allDivs, function(el) {
return el.clssName
})
// allDivs는 유사 배열이므로 map메소드가 존재하지 않는다.
// 그러나, Array prototype으로부터 map 메소드를 빌려와 this를 넘겨 map 을 실행할 수 있다.
bindメソッド
bindはい.callと同様に、この関数はthisとパラメータをバインドしますが、すぐに実行するのではなく、バインドされた関数を返します.
1番目のパラメータはthisを渡し、2番目のパラメータは必要なパラメータを渡します.fn.bind(this값, 인자1, 인자2, ...)
bindはcall,applyに比べて多くの比較的有用な使用例がある.
ケース1:イベントハンドラ
bindは、イベントハンドラがイベントオブジェクトではなく別の値を渡す場合に便利です.
複数のボタンを動的に作成し、イベントハンドラごとに異なる値をバインドする必要がある場合は、を考慮します.
次の例では、各ボタンをクリックするとalertにユーザ情報が表示されることが望ましい.
例
bindを使用してパラメータを指定できますが、すぐに実行することはできません.
この場合、この値は重要ではないのでnullのように何も渡さないことができます.
Solution
Solution1users.forEach(user => {
let btn = document.createElement('button');
btn.textContent = user.name;
btn.onclick = handleClick.bind(null, user);
target.appendChild(btn);
})
Solution2// bind를 사용하지 않고 익명 함수로 문제를 해결할 수도 있다.
users.forEach(user => {
let btn = document.createElement('button');
btn.textContent = user.name;
btn.onclick = () => {
handleClick(user)
}
target.appendChild(btn);
})
Case2: setTimeout
settimeoutは、遅延が発生した後に関数を非同期で実行する関数です.
この関数は、Windowsオブジェクトを常に明示的にこのオブジェクトにバインドする特徴があります.
このため、次の問題が発生する可能性があります.
例class Rectangle {
construcotr(width, height) {
this.width = width;
this.height = height;
}
getArea() {
return this.width * this.height
}
printArea() {
console.log('사각형의 넓이는' + this.getArea + '입니다')
}
printSync() {
// 즉시 사각형의 넓이를 콘솔에 표시한다
this.printArea();
}
printAsync() {
// 1초 후 사각형의 넓이를 콘솔에 표시한다
setTimeout(this.printArea(), 2000)
}
}
let box = new Rectangle(40, 20)
box.printSync() // '사각형의 넓이는 800 입니다'
box.printAsync() // 에러 발생
これがRectangleのインスタンスではないことをエラーで確認できます.
では、これは何の価値がありますか.printArea関数のインポート部分にはconsoleがあります.検証のためにlog(this)を追加します.
この問題を解決するためにbindを使用することができます.printAsyncセクションを次のように置き換えます.
Solution
Solution1printAsync() {
// 1초 후 사각형의 넓이가 콘솔에 표시한다
setTimeout(this.printArea.bind(this), 2000)
}
Solution2// 화살표 함수 도입
printAsync() {
// 1초 후 사각형의 넓이를 콘솔에 표시한다
setTimeout(() => {
this.printArea()
}, 2000)
}
Reference
この問題について(this), 我々は、より多くの情報をここで見つけました
https://velog.io/@ehdgusdl9177/TIL-21.04.16this
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
function foo() {
return 'bar';
}
foo()
foo.call()
foo.apply()
// null을 this로 지정한다. Math는 생성자가 아니므로 this를 지정할 필요가 없다.
Math.max.apply(null, [5, 4, 1, 6, 2]) // 6
// spread operator의 도입으로 굳이 apply를 이용할 필요가 없어졌다.
Math.max(...[5, 4, 1, 6, 2]) // 6
// '피', '땀', '눈물'을 this로 지정한다.
''.split.call('피, 땀, 눈물', ',')
// 다음과 정확히 동일한 결과를 리턴한다.
'피, 땀, 눈물'.split(',')
let allDivs = document.querySelectAll('div') // Node.js라는 유사 배열이다.
// allDivs를 this로 지정한다.
[].map.call(allDivs, function(el) {
return el.clssName
})
// allDivs는 유사 배열이므로 map메소드가 존재하지 않는다.
// 그러나, Array prototype으로부터 map 메소드를 빌려와 this를 넘겨 map 을 실행할 수 있다.
bindはい.callと同様に、この関数はthisとパラメータをバインドしますが、すぐに実行するのではなく、バインドされた関数を返します.
1番目のパラメータはthisを渡し、2番目のパラメータは必要なパラメータを渡します.
fn.bind(this값, 인자1, 인자2, ...)
bindはcall,applyに比べて多くの比較的有用な使用例がある.ケース1:イベントハンドラ
bindは、イベントハンドラがイベントオブジェクトではなく別の値を渡す場合に便利です.
複数のボタンを動的に作成し、イベントハンドラごとに異なる値をバインドする必要がある場合は、を考慮します.
次の例では、各ボタンをクリックするとalertにユーザ情報が表示されることが望ましい.
例
bindを使用してパラメータを指定できますが、すぐに実行することはできません.
この場合、この値は重要ではないのでnullのように何も渡さないことができます.
Solution
Solution1
users.forEach(user => {
let btn = document.createElement('button');
btn.textContent = user.name;
btn.onclick = handleClick.bind(null, user);
target.appendChild(btn);
})
Solution2// bind를 사용하지 않고 익명 함수로 문제를 해결할 수도 있다.
users.forEach(user => {
let btn = document.createElement('button');
btn.textContent = user.name;
btn.onclick = () => {
handleClick(user)
}
target.appendChild(btn);
})
Case2: setTimeout
settimeoutは、遅延が発生した後に関数を非同期で実行する関数です.
この関数は、Windowsオブジェクトを常に明示的にこのオブジェクトにバインドする特徴があります.
このため、次の問題が発生する可能性があります.
例
class Rectangle {
construcotr(width, height) {
this.width = width;
this.height = height;
}
getArea() {
return this.width * this.height
}
printArea() {
console.log('사각형의 넓이는' + this.getArea + '입니다')
}
printSync() {
// 즉시 사각형의 넓이를 콘솔에 표시한다
this.printArea();
}
printAsync() {
// 1초 후 사각형의 넓이를 콘솔에 표시한다
setTimeout(this.printArea(), 2000)
}
}
let box = new Rectangle(40, 20)
box.printSync() // '사각형의 넓이는 800 입니다'
box.printAsync() // 에러 발생
これがRectangleのインスタンスではないことをエラーで確認できます.
では、これは何の価値がありますか.printArea関数のインポート部分にはconsoleがあります.検証のためにlog(this)を追加します.
この問題を解決するためにbindを使用することができます.printAsyncセクションを次のように置き換えます.
Solution
Solution1
printAsync() {
// 1초 후 사각형의 넓이가 콘솔에 표시한다
setTimeout(this.printArea.bind(this), 2000)
}
Solution2// 화살표 함수 도입
printAsync() {
// 1초 후 사각형의 넓이를 콘솔에 표시한다
setTimeout(() => {
this.printArea()
}, 2000)
}
Reference
この問題について(this), 我々は、より多くの情報をここで見つけました https://velog.io/@ehdgusdl9177/TIL-21.04.16thisテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol