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をいろいろやりとりできる関数ってことかな?