Создание полифилла и параметрического объекта Function.prototype.bind

Благодаря Function.prototype.bind есть хороший способ создавать объекты с параметрическими аргументами:

var d = new (Function.prototype.bind.apply(Date, [null, 2012, 8, 3]));
console.log(d); // => Mon Sep 03 2012 00:00:00 + timezone

К сожалению, bind не поддерживается IE8 и более ранними версиями, но это покрывается многими распространенными полифиллами. один на MDN, возможно, является наиболее общий:

Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
        // closest thing possible to the ECMAScript 5 internal IsCallable function
        throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
            return fToBind.apply(this instanceof fNOP && oThis ? this : oThis,
                           aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
};

Но это приводит к странным результатам в IE:

console.log(d); // throws "Date.prototype.toString: 'this' is not a Date object"

Нечто подобное также для пользовательских классов, а не только для собственных объектов.

Я немного потерялся в этом. Можно ли решить эту проблему, просто изменив определение Function.prototype.bind? Боюсь, что нет.


person MaxArt    schedule 03.09.2012    source источник
comment
Зачем вообще нужно ссылаться на Function.prototype.bind? Разве недостаточно просто использовать Date.apply(Date, [2012, 8, 3]);?   -  person Peter Olson    schedule 03.09.2012
comment
@PeterOlson Вы получаете строку, используя это, а не объект Date. Более того, строка текущего времени. Это как позвонить Date().   -  person MaxArt    schedule 03.09.2012
comment
Вызов функции, возвращаемой Function.prototype.bind.apply(Date, [null, 2012, 8, 3]);, также возвращает строку. Он не создает объект Date. new d(), похоже, работает, если вы это имеете в виду. (console.log(d); дает мне только function () { [native code] }). Если все, что вам нужно, это использовать .apply с new, посмотрите stackoverflow.com/questions/1606797/.   -  person Felix Kling    schedule 03.09.2012
comment
@FelixKling Извините, в коде была небольшая ошибка: ключевое слово new отсутствовало. Чувак, я слишком сонный сейчас...   -  person MaxArt    schedule 03.09.2012
comment
JS предоставляет СТОЛЬКО способов стрелять в ноги   -  person zerkms    schedule 03.09.2012