Function.prototype.bind
Мой вариант 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 }()); прошлую тему удалил, там ошибка была |
Часовой пояс GMT +3, время: 01:52. |