Sibainu Relax Room

愛犬の柴犬とともに過ごす部屋

JavaScript callについて

理解が難しかった JavaScript の 「 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 はグローバルオブジェクトを参照することになります。