Function.applyの個人的な解釈
よく分からん
Netscape Communicator 4.06 以降では、call() や apply() を用いて、Person のサブクラス Person2 や Person3 を作成することができます。引数固定の場合は call()、可変個引数の場合は apply() を用います。
クラスを継承する
クラスを継承?よく分からん(´・ω・`)
難しいので三つに分けて考える (以下関数A == F:A)
1.関数間で引数を引き継ぐ
例えばF:AとF:Bってのがあったとして
F:Aに渡された引数を全部F:Bに渡したいって時は・・・
function A(){ return B.apply(this,arguments); } function B(){ var w = null; for(var i=0;i<arguments.length;i++)w += arguments[i]; return w; } var res = A(1,2,3,4,5,6,7,8,9); console.log(res); -> 45
この様になります
つまりB.apply(this,arguments)はB(arguments[0],arguments[1],arguments[3],......)
と同じ意味になります
2.相手関数のthisをセットする
普通Function.applyはFunction.apply(this,arguments)の様に使いますが
この第一引数がセットする内容になっています・・・たぶん・・・
例えば
function A(){ this.str = "hoge"; this.value = "foo"; return B.apply(this,arguments); } function B(){ var w = null; for(var i=0;i<arguments.length;i++)w += arguments[i]; return this.str+"|"+w+"|"+this.value; } var res = A(1,2,3,4,5,6,7,8,9); console.log(res) -> hoge|45|foo
こんな感じです
B.apply(this,arguments)のthisはF:Aのthisなので
F:AのthisがF:Bにthisにセットされたのが分かると思います
またthisじゃなくてもObjectとかJSONでも同じようなことができます
function A(){ var h = {str:"foo",value:"bar"}; return B.apply(h,arguments); } function B(){ var w = null; for(var i=0;i<arguments.length;i++)w += arguments[i]; return this.str+"|"+w+"|"+this.value; } var res = A(1,2,3,4,5,6,7,8,9); console.log(res) -> foo|45|bar
ちなみにB.apply(null,arguments)やB.apply(undefined,arguments)でも同じ結果になります(なんで?)
3.相手関数からthisを受ける
applyは相手関数のthisをセットできますが受けることもできます
例えば
function A(){ B.apply(this,arguments); } function B(){ for(var i=0;i<arguments.length;i++)this[i] = arguments[i]; } var res = new A("hoge","foo","bar","baz"); console.log(res[0]+"|"+res[2]); -> hoge|bar
ただしこの様に書いてしまうと・・・
function A(){ var h = {str:"hoge",value:"foo"}; B.apply(h,arguments); } function B(){ for(var i=0;i<arguments.length;i++)this[i] = arguments[i]; } var res = new A("hoge","foo","bar","baz"); console.log(res[0]+"|"+res[2]); -> undefined|undefined
このようになってしまいます
なぜかというと相手関数のthisを受けるのはapplyの第一引数だからです
ですからこのようにObjectやJSONを使う場合はこう書いたほうが良さそうです
function A(){ var h = {str:"hoge",value:"foo"}; B.apply(h,arguments); return h; } function B(){ for(var i=0;i<arguments.length;i++)this[i] = arguments[i]; } var res = A("hoge","foo","bar","baz"); console.log(res[0]+"|"+res[2]); -> hoge|bar
結局applyって
関数間で引数とかthisをいろいろやりとりできる関数ってことかな?