Comments 31
Актуально. Как раз задавался вопросом: как разрулить ситуацию с IE и считал до сих пор эту возможность некроссбраузерной.
отказаться от ослов ниже девятой версии
Лет через пять, если повезет. ))
Имхо не совсем оправдано.
Да — вы получаете более менее удобный интерфейс, более того — проперти можно даже в IE6 запустить(через VBScript)
Но давайте будем реалистами — jsperf.com/getters-and-setters — доступ к проперти в 10-20 раз медленее чем доступ к переменной.
И в теже 10-20 раз медленее чем вызов функции( setValue\getValue)
Это крутовато.
Кстати — с недавних пор в ФФ4 вызов функции стал раза в 3 быстрее доступа к переменной — кто может обьяснить?
Да — вы получаете более менее удобный интерфейс, более того — проперти можно даже в IE6 запустить(через VBScript)
Но давайте будем реалистами — jsperf.com/getters-and-setters — доступ к проперти в 10-20 раз медленее чем доступ к переменной.
И в теже 10-20 раз медленее чем вызов функции( setValue\getValue)
Это крутовато.
Кстати — с недавних пор в ФФ4 вызов функции стал раза в 3 быстрее доступа к переменной — кто может обьяснить?
тесты в студию. у меня другие данные
повторюсь — jsperf.com/getters-and-setters
гомэн, не заметил. это кривой бенчмарк со странными результатами. вызов метода, который получает значение поля ну никак не может быть быстрее прямого получения значения поля.
по моим тестам разница не более 2 раз
по моим тестам разница не более 2 раз
такая магия только в самой последней версии хрома.
Также резульаты теста ОЧЕНЬ сильно плавают от системы к системе.
В смысле под бунтой\маком\виндой на одинаковых билдах браузеров будут стабильно разные результаты.
Разные в разы. Фантастика
Также резульаты теста ОЧЕНЬ сильно плавают от системы к системе.
В смысле под бунтой\маком\виндой на одинаковых билдах браузеров будут стабильно разные результаты.
Разные в разы. Фантастика
Потестил в хроме, гетеры / сеттеры в 3 раза медленнее setValue / getValue / прямого доступа.
Тестил в консоли:
a = { a: 1, get aa(){ return this.a; }, set aa(a){ this.a = a; }, getA: function() { return this.a; }, setA: function(a) { this.a = a; } }
function test(f, i){ console.time('test'); while(--i > 0) { f(); } console.timeEnd('test'); };
test(function(){ a.a }, 1000000);
test(function(){ a.aa }, 1000000);
test(function(){ a.getA() }, 1000000);
test(function(){ a.a=10 }, 1000000);
test(function(){ a.aa=10 }, 1000000);
test(function(){ a.setA(10) }, 1000000);
На jsperf.com/getters-setters-vs-direct результаты получились совсем другие.
a = { a: 1, get aa(){ return this.a; }, set aa(a){ this.a = a; }, getA: function() { return this.a; }, setA: function(a) { this.a = a; } }
function test(f, i){ console.time('test'); while(--i > 0) { f(); } console.timeEnd('test'); };
test(function(){ a.a }, 1000000);
test(function(){ a.aa }, 1000000);
test(function(){ a.getA() }, 1000000);
test(function(){ a.a=10 }, 1000000);
test(function(){ a.aa=10 }, 1000000);
test(function(){ a.setA(10) }, 1000000);
На jsperf.com/getters-setters-vs-direct результаты получились совсем другие.
доступ к проперти в 10-20 раз медленее чем доступ к переменной.
Я делаю приложение, где выполняются тысячи операций в секунду. И поверьте мне — они не тормозят.
lookup и define — да, тормозят, но при должном подходе они вызываются крайне редко)
Эээ, получается ты каждому новому экземпляру отдельно прописываешь ассессоры?
В пицот раз медленнее, чем унаследовать стандартный getProperty/setProperty из прототипа же! Не?
И, бтв, если ты в анонимной фукнции пишешь что-то типа
то, имхо, красивее эту самую фукнцию вызывать через .call(window, Object), вместо просто (Object). Нагляднее как-то, что-ли.
MyClass = function (param) {
var property = param;
accessors.define(this, 'property', {
set: function (value) {
property = value;
},
get: function () {
return property;
}
});
};
В пицот раз медленнее, чем унаследовать стандартный getProperty/setProperty из прототипа же! Не?
И, бтв, если ты в анонимной фукнции пишешь что-то типа
this.accessors = {
lookup: lookup,
define: define
};
то, имхо, красивее эту самую фукнцию вызывать через .call(window, Object), вместо просто (Object). Нагляднее как-то, что-ли.
то, имхо, красивее эту самую фукнцию вызывать через .call(window, Object), вместо просто (Object). Нагляднее как-то, что-ли.
А на сервере — нету никакого
window
;)Эээ, получается ты каждому новому экземпляру отдельно прописываешь ассессоры?
На самом деле это всего лишь пример. Я делаю так:
MyClass = function(){};
MyClass.prototype = {
get property ( ) {},
set property (v) {}
};
А вышеуказанная библиотека нужна в первую очередь для наследования и некоторой специфической магии
А на сервере — нету никакого window ;)
А еще на сервере не надо писать кроссбраузерный код :)
Согласен) Но когда делаешь либу — надо предвидеть такие вещи.
Скажем, LibCanvas может используется и на сервере для операций с точками, прямоугольниками, или для анимированного изменения свойств.
Таким образом, все эти объекты тянут кое-какие костыли в библиотеке и на сервер.
Скажем, LibCanvas может используется и на сервере для операций с точками, прямоугольниками, или для анимированного изменения свойств.
Таким образом, все эти объекты тянут кое-какие костыли в библиотеке и на сервер.
Если бы можно было игнорировать ослов, жизнь была бы прекрасней :)
В блоге WebReflection была статья, описывающая подобные ухищрения. Вот исходник библиотечки devpro.it/code/212.html
Не, ну там ведь не совсем то. Я про настоящие сеттеры, а не про гибридные пишу)
На тему того, что описано в статье на WebReflection, я писал мутатор для Мтулуз:
Код мутатора:
На тему того, что описано в статье на WebReflection, я писал мутатор для Мтулуз:
var MyClass = new Class({
Properties: {
foo: {
set: function (foo) {
this._foo = foo;
},
get: function () {
return this._foo;
}
}
}
});
var instance = new MyClass();
instance.foo(123);
alert(instance.foo());
Код мутатора:
Class.Mutators.Properties = function (properties) {
for (var name in properties) (function (name, prop) {
this.prototype[name] = function (value) {
if (arguments.length) {
// setter
if (!prop.set) throw new Error('No setter for ' + name);
prop.set.call(this, value);
return this;
} else {
// getter
if (!prop.get) throw new Error('No getter for ' + name);
return prop.get.call(this);
}
};
}.call(this, name, properties[name]));
};
Ох, а мы всё ещё ie6 поддерживаем…
я правильно понял, что работать будет только в:
IE10, FF 2.0+, Safari 3.0+, Chrome 1.0+, Opera 9.5+
(источник: robertnyman.com/javascript/javascript-getters-setters.html)
?
IE10, FF 2.0+, Safari 3.0+, Chrome 1.0+, Opera 9.5+
(источник: robertnyman.com/javascript/javascript-getters-setters.html)
?
Sign up to leave a comment.
Кроссбраузерные аксессоры в JavaScript