【JavaScript】call・apply

  • 関数のthisを置き換える
    call・apply共に関数を呼び出し、呼び出した関数のthisを第1引数に指定したオブジェクトに置き換える。
var func  = function(){
    console.log(this);
}

func();
func.call({hoge: 1});
func.apply({hoge: 2});
//出力
//func()はwindowオブジェクトが出力される(長すぎるため省略)
{
  hoge: 1
}
{
  hoge: 2
}

違い

  • 第2引数の値
    callは第2引数以降に値を複数受け取る。applyは第2引数に1つの配列を受け取る。
var func  = function(a1, a2){
    console.log(this);
    console.log(a1);
    console.log(a2);
}

func.call({hoge: 1}, "c1", "c2");
func.apply({hoge: 2}, ["a1", "a2"]);
//出力
{
  hoge: 1
}
"c1"
"c2"
{
  hoge: 2
}
"a1"
"a2"

使用例

  • なりすまし
    callやapplyを利用すると本来は利用できない機能が、利用可能なオブジェクトになりすまして利用できるようになる。
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
</ul>   
var liText1 = ( document.querySelectorAll( "li" ) ).map( function (e) {
    return e.textContent;
});
console.log(liText1)


var liText2 = Array.prototype.map.call( document.querySelectorAll( "li" ), function (e) {
  return e.textContent;
});
console.log(liText2)
//liText1 はmap()を持っていないため実行できずエラー
Uncaught TypeError: document.querySelectorAll(...).map is not a function

//liText2 はmap()を持っているArrayオブジェクトになりすますことで実行できる
["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]

参考