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に変数名が混じっているので、一般的なサービスでは最適化できないから。