Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 30.08.2011, 03:54
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

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

}());


прошлую тему удалил, там ошибка была

Последний раз редактировалось Octane, 30.08.2011 в 14:50.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск