Мой вариант Function.prototype.bind
http://jsfiddle.net/Octane/Fm8P3/
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
function newApply(Constructor, args) {
var i = 0, len = args.length, argNames = [];
while (i < len) {
argNames.push("arg" + i);
i++;
}
argNames = argNames.join(",");
return Function("Constructor", argNames, "return new Constructor(" + argNames + ")").apply(window, [Constructor].concat(args));
}
return function (boundThis) {
var targetFunc = this, boundArgs = Array.prototype.slice.call(arguments, 1);
function boundFunc() {
var allArgs, len;
function NOP() {}
if (boundFunc._protoMagic) {
boundFunc._protoMagic = false;
NOP.prototype = this;
NOP.prototype.constructor = targetFunc;
return new NOP;
}
else {
allArgs = boundArgs.concat(Array.prototype.slice.call(arguments));
len = allArgs.length;
}
if (this && this.constructor == boundFunc) {
boundFunc._protoMagic = true;
NOP.prototype = len > 1 ? newApply(targetFunc, allArgs) : (len ? new targetFunc(allArgs[0]) : new targetFunc);
boundFunc.prototype = new NOP;
boundFunc.prototype.constructor = boundFunc;
return new boundFunc;
}
return len > 1 ? targetFunc.apply(boundThis, allArgs) : (len ? targetFunc.call(boundThis, allArgs[0]) : targetFunc.call(boundThis));
}
boundFunc._protoMagic = false;
return boundFunc;
};
}();
}
В отличие от
примера на MDN, здесь для [[TargetFunction]] честно выполняется [[Construct]], а так же корректно обрабатывается случай
boundFunc.call(new boundFunc)
(function () {
function F(x) {
if (this.constructor == F) {
this.x = x;
}
return this.x;
}
var G = F.bind({x: 1});
var g = new G(2);
alert(G.call(g));//должно быть 1, а MDN вариант выдаст undefined
alert(G.call(new F(3)));//должно быть 1, а MDN вариант выдаст undefined
}());
bound-функции не имеют прототипа, конечно удалить его не получится, но добавлять свойства бесполезно:
(function () {
function F(x) {
if (this.constructor == F) {
this.x = x;
}
return this.x;
}
var G = F.bind({x: 1});
try {
G.prototype.y = 3;
}
catch (e) {
}
var g = new G(2);
alert(g.y);//должно быть undefined, а MDN вариант выдаст 3
}());
прошлую тему удалил, там ошибка была