Function.prototype.applyとかArray.prototype.spliceのIE5用のコード

applyはObject以外のものをthisにしようとする場合、x.__applyに代入できないので、constructorからprototypeを辿って、そこに入れる感じ。

Array関連はcall等を一切使わず、forだけで処理するように作りました。

あと、全体をfunctionで囲んだ無名関数の実行にするとうまく適用されない。var P = Function.prototypeとかしたから動かなかった。NativeObject.prototypeだけなんか処理が違うっぽい。

一応、全部、動作確認したつもり。

Function.prototype.apply || (Function.prototype.apply = function (x, y) {
	x = x || window;
	y = y ||[];
	x.__apply = this;
	if (!x.__apply) x.constructor.prototype.__apply = this;
	var r, j = y.length;
	switch (j) {
		case 0: r = x.__apply(); break;
		case 1: r = x.__apply(y[0]); break;
		case 2: r = x.__apply(y[0], y[1]); break;
		case 3: r = x.__apply(y[0], y[1], y[2]); break;
		case 4: r = x.__apply(y[0], y[1], y[2], y[3]); break;
		case 5: r = x.__apply(y[0], y[1], y[2], y[3], y[4]); break;
		case 6: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5]); break;
		case 7: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6]); break;
		case 8: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7]); break;
		case 9: r = x.__apply(y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7], y[8]); break;
		default:
			var a = [];
			for (var i = 0; i < j; ++i)
				a[i] = 'y[' + i + ']';
			r = eval('x.__apply(' + a.join(',') + ')');
			break;
	}
	delete x.__apply ? x.__apply : x.constructor.prototype.__apply;
	return r;
});
Function.prototype.call || (Function.prototype.call = function () {
	var a = arguments, x = a[0], y = [];
	for (var i = 1, j = a.length; i < j; ++i)
		y[i - 1] = a[i]
	return this.apply(x, y);
});
Array.prototype.pop || (Array.prototype.pop = function () {
	var r = this[this.length - 1];
	--this.length;
	return r;
});
Array.prototype.push || (Array.prototype.push = function () {
	for (var a = arguments, i = 0, j = a.length, l = this.length; i < j; ++i)
		this[l + i] = a[i];
	return this.length;
});
Array.prototype.shift || (Array.prototype.shift = function () {
	var r = this[0];
	for(var i = 1, j = this.length; i < j; ++i)
		this[i - 1] = this[i];
	--this.length;
	return r;
});
Array.prototype.unshift || (Array.prototype.unshift = function () {
	var a = arguments, l = a.length, j = this.length += l - 1;
	for (var i = j; i >= l; --i)
		this[i] = this[i - l];
	for (var i = 0; i < l; ++i)
		this[i] = a[i];
	return j;
});
Array.prototype.splice || (Array.prototype.splice = function (x, y) {
	var a = arguments, s = a.length - 2 - y, r = this.slice(x, x + y);
	if (s > 0) {
		for (var i = this.length - 1, j = x + y; i >= j; --i)
			this[i + s] = this[i];
	}
	else if (s < 0) {
		for (var i = x + y, j = this.length; i < j; ++i)
			this[i + s] = this[i];
		this.length += s;
	}
	for (var i = 2, j = a.length; i < j; ++i)
		this[i - 2 + x] = a[i];
	return r;
});

動作確認用

手動で最適化しているのは、evalに変数名が混じっているので、一般的なサービスでは最適化できないから。