Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   FAQ Баги браузеров. (https://javascript.ru/forum/offtopic/33616-faq-bagi-brauzerov.html)

Octane 14.04.2014 01:25

Не долго я радовался простому способу создания Array generic methods, баг Array.splice в IE8:
var obj = {
	"0": "a",
	"1": "b",
	"2": "c",
	length: 3
};

[].splice.call(obj, 1, 1);

alert(JSON.stringify(obj)); //→ {"0":"a","1":"c","2":"c","length":2}
           //остальные браузеры {"0":"a","1":"c","length":2}

Большинство результатов в Google с жалобой на то, что 2-й аргумент в IE обязательный, но этот баг тоже нагуглился http://stackoverflow.com/questions/1...ss-browser-ie8

monolithed 14.04.2014 11:05

var holder = { 
    i: 0, 
    toString: function() {
        return this.i++;
    } 
}; 

var object = {}; 
object[holder] = holder + ''; 
object[holder] = holder + ''; 

object; // ?

devote 14.04.2014 11:56

Цитата:

Сообщение от Octane
Array generic methods, баг Array.splice в IE8:

Старый баг, я на него наткнулся еще когда селекторы писал, решается так:
(function(o){
    Array.prototype.splice.call(o, 1, 1);
    return o[1] !== 1;
}({"0": 0, "1": 1, "length": 2})) || new function() {
    var splice = Array.prototype.splice;
    Array.prototype.splice = function(offset, count) {
        var result = splice.apply(this, arguments);
        if (!(this instanceof Array)) {
            while(count--) {
                delete this[this.length + count];
            }
        }
        return result;
    }
};
 
[].splice.call(obj, 1, 1);
 
alert(JSON.stringify(obj)); // {"0":"a","1":"c","length":2}

Octane 14.04.2014 14:06

Цитата:

Сообщение от devote
Старый баг, я на него наткнулся еще когда селекторы писал, решается так:

Обычно push.call и slice.call хватало, до splice как то дело не доходило) Да и сейчас наткнулся, потому что от нечего делать метод array.remove писал.

Цитата:

Сообщение от monolithed
var holder = { 
    i: 0, 
    toString: function() {
        return this.i++;
    } 
}; 

var object = {}; 
object[holder] = holder + ''; 
object[holder] = holder + ''; 

object; // ?

{"0":"1","2":"3"} //IE8
{"1":"0","3":"2"} //другие браузеры

Я так понял в IE8 сначала создается object[holder] = undefined, а потом выполняется присваивание вычисленного значения

Aetae 14.04.2014 14:32

Вообще по общей логике javascript(исполнение слева-направо) IE тут прав, ибо по сути то:
var holder = {
    i: 0,
    toString: function() {
        return this.i++;
    }
}
var object = {};
object[holder.toString()] = holder.toString() + '';
object[holder.toString()] = holder.toString() + '';
 
alert(JSON.stringify(object));

devote 14.04.2014 14:54

Не знаю к чему вы это, но я тоже внесу свою лепту ;)
new function() {
    var i = 0;
    Object.defineProperty(window, 'holder', {
        configurable: true,
        get: function() {
            return i++;
        }
    });
}

var object = {};
object[holder] = holder;
object[holder] = holder;
 
alert(JSON.stringify(object));

Aetae 14.04.2014 15:16

devote, к тому что toString ведёт себя не как гетер, а как хз что.
Интересно спеки говорят что нибудь об этом?..

devote 14.04.2014 15:31

Цитата:

Сообщение от Aetae
к тому что toString ведёт себя не как гетер, а как хз что.

Ну вполне норм себя ведет, вызывается тогда когда нужно конвертнуть значение в строку... Все вполне разумно и правильно.

Понятно дело что в этом случае браузеру нужно гадать, конвертить или нет:
object[holder]
вот так он поймет конечно что нужно вызвать toString, так как явно указывает на это:
object[holder + '']

Aetae 14.04.2014 15:37

devote, не, понятно конечно что ситуация неопределённая, но holder то объект, так что конвертить полюбасу придётся. Я лично в данной ситуации на стороне ie.

monolithed 14.04.2014 15:38

Цитата:

Сообщение от devote
object[holder + '']

Ага, хоть кто-то на это обратил внимание :victory:


Часовой пояс GMT +3, время: 23:32.