Sibainu Relax Room

柴犬と過ごす

JavaScript callについて

理解が難しかったcall がやっと少し分かったような気になりましたので、その理解を書き留めます。

最初の call

copy

function man(firstname, lastname) {
  this.firstname = firstname;
  this.lastname = lastname;
}

function Member(firstname, lastname) {
  man.call(this, firstname, lastname);
  this.category = 'member';
}

obj = new Member('saito', 'itiro');

window.alert(obj.firstname);
// => "saito"                         A

window.alert(obj.lastname);
// => "itiro"                         B

obj.firstname = "japan"
obj.lastname = "union"

window.alert(obj.firstname);
// => "japan"                         C

window.alert(obj.lastname);
// => "union"                         D

A の実行

B の実行

C の実行

D の実行

理解したところ

call()について、this を that で解説した本を読みましたが理解できませんでした。
原点に戻り MDN の開発者向けのウェブ技術を見たところ、次のように解説しています。

call() はあるオブジェクトに所属する関数やメソッドを、別なオブジェクトに割り当てて呼び出すことができます。
call() は関数やメソッドに this の新しい値を提供します。

この解説を読んで、例で言うと Member.man(firstname, lastname) と考えると、私にはすっきりすると思いました。
つまり、一時的に man というメソッドを作り Member オブジェクトの中に 変数 firstname = saito, 変数 lastname = itiro を割り当てて(作成して)、その後 Member.firstname、Member.lastname で呼び出せるのだと理解したのです。

無名関数

無名関数を作成しそれに所属する関数やメソッドを、 call を使用してオブジェクトに対して割り当てて呼び出すということもできます。
まさしく、man.No、man.print() 呼び出しています。

copy

var man = { firstname: 'saito', lastname: 'itiro' };

(function () {
  this.No
  this.print = function() {
    window.alert(this.No + ': ' + this.firstname
                  + ' ' + this.lastname);
  }
}).call(man);

man.No = 10;
man.print();

ブラウザでオープン

最初の引数がない場合

最初の引数が渡されないと、 this の値はグローバルオブジェクトに結び付けられます。

copy

var data = 'Global data';

function display() {
  window.alert(this.data);
}

display.call();  //=> Global data

ブラウザでオープン

null.display() ですから、 this はグローバルオブジェクトを参照することになります。