Цитата:
|
Цитата:
|
Короче тут обсуждали https://twitter.com/DmitryKorobkin/s...81153034596354
Если фиксить через new NOP, то возникает проблема: Object.create(null) instanceof Object → true, а так быть не должно, поэтому последний вариант:
//IE9-11 Object.create bug fix
(function () {
var object = Object.create({});
object[0] = null;
return object.hasOwnProperty(0); //→ false in IE9-11
}()) || new function () {
var create = Object.create;
Object.create = function (prototype, properties) {
//Object.defineProperties fixes a bug
if (properties) {
return create(prototype, properties);
}
//If Object.create works via new NOP, then
//Object.create(null) instanceof Object → true,
//but it's wrong.
//https://twitter.com/WebReflection/status/454342010288078848
if (prototype === null) {
return create(null, {
"": {
configurable: true,
writable: true
}
});
}
function NOP() {}
NOP.prototype = prototype;
return new NOP;
};
};
да, теперь для Object.create(null), метод Object.getOwnPropertyNames будет возвращать лишнее пустое свойство, но лучше варианта пока не придумал. |
А не проще тогда уж поправить hasOwnProperty
//IE9-11 Object.create bug fix
(function () {
var object = Object.create({});
object[0] = null;
return object.hasOwnProperty(0); //> false in IE9-11
}()) || new function () {
var hasOwnProperty = Object.prototype.hasOwnProperty;
Object.prototype.hasOwnProperty = function(prop) {
// если числовое свойство ищем
return +prop == prop ?
Object.getOwnPropertyNames(this).indexOf(""+prop) != -1 :
hasOwnProperty.apply(this, arguments);
};
};
|
Тогда и getOwnPropertyDescriptor, и propertyIsEnumerable фиксить придется, может еще что-нибудь
|
Баг интерфейса в FF28, замечен в винде:
Встроенный редактор JS иногда перестает исполнять код. Это бывает неочевидно, например, когда код чисто логический и не подразумевает каких-либо визуальных эффектов. Поэтому сопровождайте его хотя бы console.log, если ниче не логирует - лечится открыванием нового окна редактора. |
Дзен-трансгуманист, ты не сюда пости, а в баг-трекер мозиллы:)
|
Цитата:
|
Цитата:
//IE9-11 Object.create bug fix
(function () {
var object = Object.create({});
object[0] = null;
return object.hasOwnProperty(0); //> false in IE9-11
}()) || new function () {
var create = Object.create;
Object.create = function (prototype, properties) {
var isExecNum = properties && Object.getOwnPropertyNames(properties).indexOf("0") != -1;
if (!isExecNum) {
properties = properties || {};
/**
* Нужно добавить именно числовое свойство, иначе не будет работать
* например такой вариант не работает:
* var o = Object.create({}, {"": {configurable: true}});
* delete o[""];
* o[0] = null;
* o.hasOwnProperty(0) // -> false
* но если вместо пустой строки поставить число, то все работает хорошо
*/
properties["0"] = {
configurable: true
};
}
var object = create.call(this, prototype, properties);
if (!isExecNum) {
delete object["0"];
delete properties["0"];
}
return object;
};
};
|
О это хорошо, теперь фикс ничем не помешает.
//IE9-11 Object.create bug fix
(function () {
var object = Object.create({});
object[0] = null;
return object.hasOwnProperty(0); //→ false in IE9-11
}()) || new function () {
var create = Object.create;
Object.create = function (prototype, properties) {
var object;
if (properties) {
//Object.defineProperties fixes a bug
object = create(prototype, properties);
}
else {
//numeric key fixes a bug,
//it can be removed after,
//unlike alphabetic key
object = create(prototype, {
"0": {
configurable: true
}
});
delete object[0];
}
return object;
};
};
|
Цитата:
|
Octane,
Твой вариант не будет работать если я сделаю так:
var o = Object.create({}, {});
o[0] = null;
o.hasOwnProperty(0); // false
|
Цитата:
|
melky,
Зачем? Просто для ИЕ нужно проинициализировать объект |
Цитата:
defineProperties только enumerable свойства берет из объекта с дескрипторами devote, твой вариант не работает, если сделать так:
var desc = Object.create({}, {"0": {}});
var obj = Object.create({}, desc);
obj[1] = 1;
console.log(obj.hasOwnProperty(1));
а если вместо getOwnPropertyNames будем использовать keys, можем случайно удалить non-enumerable свойство. Вряд ли конечно кто-то так будет делать, но хочется 100% вариант)----------- наверное лучше getOwnPropertyDescriptor использользовать |
//IE9-11 Object.create bug fix
//http://webreflection.blogspot.ru/2014/04/all-ie-objects-are-broken.html
(function () {
var object = Object.create({});
object[0] = null;
return object.hasOwnProperty(0); //→ false in IE9-11
}()) || new function () {
var create = Object.create;
Object.create = function (prototype, properties) {
var object = create(prototype, properties);
if (!Object.hasOwnProperty.call(object, 0)) {
//numeric key fixes a bug,
//it can be removed after,
//unlike alphabetic key
Object.defineProperty(object, 0, {
configurable: true
});
delete object[0];
}
return object;
};
};
|
Octane,
Да отличное решение. Мои тесты все прошел. |
Цитата:
new function () {
:) А еще есть вопрос: это alert(Object.hasOwnProperty) в каком стандарте написано? |
Цитата:
Object.prototype.hasOwnProperty Да и это тоже смущает: var object = create(prototype, properties);Как то все же лучше делать/видеть так: var object = create.call(this, prototype, properties);Потому как не сделав этого, мы лишаем прога передать иной контекст. Хотя конечно в данном случае он мало чем поможет. |
Цитата:
void function () {
return {
// ...
};
}();
Считаешь, что эта лучшей? ;) |
Цитата:
Object.prototype.test = 1;
alert(Object.test);
|
Цитата:
//IE9-11 Object.create bug fix
//http://webreflection.blogspot.ru/2014/04/all-ie-objects-are-broken.html
(function() {
var polyfill = {
isRequired: function() {
var object = Object.create({});
object[0] = null;
return !object.hasOwnProperty(0); //→ false in IE9-11
},
apply: function() {
var create = Object.create;
Object.create = function(prototype, properties) {
var object = create(prototype, properties);
if(!Object.hasOwnProperty.call(object, 0)) {
//numeric key fixes a bug,
//it can be removed after,
//unlike alphabetic key
Object.defineProperty(object, 0, {
configurable: true
});
delete object[0];
}
return object;
};
}
};
if(polyfill.isRequired()) {
polyfill.apply();
}
}());
С английским мог ошибиться, но суть должна быть ясна :) |
Цитата:
Цитата:
Цитата:
|
nerv_,
Object.prototype[0] = 1; alert([][0]); |
Цитата:
Object.prototype[0] = 1;
alert([][0]);
alert(''[0]);
alert(0[0]);
Цитата:
Дело не в "красивей". Понятней (как мне кажется). А объект, как создаться, так и уничтожится, если он не нужен. Впрочем, это лишь мое мнение :) |
Цитата:
var foo = function () {};
new foo;
Что тут ненормального? |
Из вариантов создания локального контекста по условию
namespace.property || new function () {
…
};
//или
if (!namespace.property) {
(function () {
…
}());
}
//или
(function () {
if (!namespace.property) {
…
}
}());
//или
(function () {
if (!namespace.property) {
return false;
}
…
return true;
}());
я выбрал для себя первыйа это
(function () { /*test case*/ }()) || new function () {
…
};
уже уже вытекающеея бы конечно написал бы
new function () { /*test case*/ } || new function () {
…
};
но примитивное значение из конструктора вернуть нельзя, для него автоматически выполнится Object(value), которое будет всегда true |
Цитата:
alert(+new function () {
this.valueOf = function () {
return 1;
};
});
:) Цитата:
namespace.property || void function () {
...
}();
|
Кстати, что-то не понял, думал let уже есть во всех браузерах, но почему-то Aurora 30 ошибку выдает. Вроде в Firefox это первым появлялось.
Ждал, что догадаются сделать, чтобы работало так:
let label: {
//local scope
}
и чтобы метка была опциональной, а вся конструкция работала в выражении
window.Anything || let {
…
}
но мечты не сбываются. |
И не говори...
var array = []; for (let i = 0; i < 2; i++) array.push(() => i); array[0](); // 0 - Traceur, 2 - FF array[1](); // 1 - Traceur, 2 - FF Еще и скобочки лишние () писать нужно :( |
Не долго я радовался простому способу создания 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 |
var holder = {
i: 0,
toString: function() {
return this.i++;
}
};
var object = {};
object[holder] = holder + '';
object[holder] = holder + '';
object; // ?
|
Цитата:
(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}
|
Цитата:
Цитата:
{"0":"1","2":"3"} //IE8
{"1":"0","3":"2"} //другие браузеры
Я так понял в IE8 сначала создается object[holder] = undefined, а потом выполняется присваивание вычисленного значения |
Вообще по общей логике 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));
|
Не знаю к чему вы это, но я тоже внесу свою лепту ;)
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));
|
devote, к тому что toString ведёт себя не как гетер, а как хз что.
Интересно спеки говорят что нибудь об этом?.. |
Цитата:
Понятно дело что в этом случае браузеру нужно гадать, конвертить или нет: object[holder]вот так он поймет конечно что нужно вызвать toString, так как явно указывает на это: object[holder + ''] |
devote, не, понятно конечно что ситуация неопределённая, но holder то объект, так что конвертить полюбасу придётся. Я лично в данной ситуации на стороне ie.
|
Цитата:
|
| Часовой пояс GMT +3, время: 19:58. |