Цитата:
|
Цитата:
|
Короче тут обсуждали 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, время: 13:23. |