Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   XDR Class — реализация классов с аксессорами для IE8 (https://javascript.ru/forum/project/37074-xdr-class-%E2%80%94-realizaciya-klassov-s-aksessorami-dlya-ie8.html)

FINoM 06.04.2013 21:40

XDR Class — реализация классов с аксессорами для IE8
 
Всем привет. Решил показать очередную имплементацию классов для JS, но с поддержкой геттеров и сеттеров с помощью Object.defineProperty, работающую в IE8. Идея очень проста: для нормальных браузеров использовать тривиальное наследование, которое можно найти в любом учебнике по JS, а для IE8 возвращать экземпляр XDomainRequest (или просто XDR), расшрияя нужными свойствами (то есть протоип менять не рекомендуется, список свойств должен быть статичным, как в работе devote).

Для тех, кто не в курсе, IE8 поддерживает Object.defineProperty для DOM объектов, XDR, в этом случае, наиболее привлекателен, так как его экземпляр имеет всего 7 свойств + 3 у прототипа.

Object.defineProperty для IE8 поддерживается кое-как. Более подробно можно прочесть в этой теме: http://javascript.ru/forum/offtopic/...rty-v-ie8.html

Поэтому я настойчиво рекомендую использовать в качестве элементов дескриптора только get и set.

Документации никакой нет, но появится после успешного завершения работы над фреймворком (превью которого я покажу чуть позже). Код выложил в репозиторий: https://github.com/finom/xdr-class/b...r/xdr-class.js (для того, чтоб проверить, просто выкачайте репозиторий и запустите index.html, сюда и на jsFiddle вставить код не могу из-за политик безопасности в IE)

Функция требует underscore (хотя его можно легко убрать).
A = Class({
    a1: 'Aa1',
    a2: 'Aa2',
    aMethod1: function(arg) {
		Object.defineProperty( this, 'x', {
			get: function() {
				return 'X Property'
			},
			set: function( v ) {
				console.log( 'Message from "x" setter, value is: ', v );
			}
		});
        console.log( 'A.Method1 call, arg is: ', arg )
    }
});

B = Class({
    'extends': A, // кавычки обязательны (для подсветки и чтоб не вызвать ошибки в IE), но 'extends' можно заменить на extend без кавычек
    b1: 'Bb1',
    b2: 'Bb2',
    a2: 'Ba2',
    constructor: function() {
        console.log( 'B.constructor call' );
    }
});

C = Class({
    'extends': B,
    c1: 'Cc1',
	b1: 'Cb1',
    constructor: function() {
        this.aMethod1( 'BLAH' );
		this.x = 'New X Value';
        B.call( this, arguments );
        console.log( 'Properties: ', this.c1, this.b1, this.b2, this.a1, this.a2 );
    },
    aMethod1: function() {
        console.log( 'C.method call' );
        B.prototype.aMethod1.apply( this, arguments );
    }
});

new C;


Из todo: добавить метод .instanceOf и что-то придумать с вызовом родительских методов (B.prototype.aMethod1.call( this ) немного надоел).

devote 06.04.2013 22:22

Цитата:

Сообщение от FINoM
а для IE8 возвращать экземпляр XDomainRequest (или просто XDR)

любопытно сколько каждый экзепляр отжирает памяти :)

FINoM 06.04.2013 22:28

Цитата:

Сообщение от devote
любопытно сколько каждый экзепляр отжирает памяти

хз, не замерял, но после создания миллиона инстанцов, комп не глючил. Понимаю, что это не объективная оценка, чуть позже проверю (и скорость по сравнению с Хромом, и память).

FINoM 06.04.2013 23:21

Сделал небольшую пробу по памяти: перед запуском ИЕ отжирал 30 МБ, на пике съедал 120 МБ, после окончания работы скрипта таск менеджер показал 100МБ. То есть миллион инстанцов отжирают 70—90МБ. Да, опять же, это не глубокое тестирование:
console.log = function() {};
console.time( '1' );
for(var i = 0; i < 1000000; i++) new C;
console.timeEnd('1');

Небольшой замер скорости:
В Хроме 26195.000ms (просто для сравнения)
В ИЕ 10 15683ms
В ИЕ 8 112826ms (всего лишь в ~4 раза медленнее Хрома. Еще раз отмечу, в Хроме используется тривиальное наследование).

FINoM 07.04.2013 01:16

Дальше можно делать всё, что душе угодно, например:
MainClass = Class({
  define: function( key, descriptor ) {
    Object.defineProperty( this, key, descriptor );
  }
});

MyClass = Class({
  'extend': MainClass,
  constructor: function() {
    this.define( 'prop', { get: function() { return 'bla'; }, set: function(v) {alert( v )}} );
  }
});

melky 07.04.2013 08:46

Цитата:

Сообщение от FINoM (Сообщение 244585)
Сделал небольшую пробу по памяти: перед запуском ИЕ отжирал 30 МБ, на пике съедал 120 МБ, после окончания работы скрипта таск менеджер показал 100МБ. То есть миллион инстанцов отжирают 70—90МБ. Да, опять же, это не глубокое тестирование:
console.log = function() {};
console.time( '1' );
for(var i = 0; i < 1000000; i++) new C;
console.timeEnd('1');

Небольшой замер скорости:
В Хроме 26195.000ms (просто для сравнения)
В ИЕ 10 15683ms
В ИЕ 8 112826ms (всего лишь в ~4 раза медленнее Хрома. Еще раз отмечу, в Хроме используется тривиальное наследование).

похоже, что в тесте экземпляры сразу убиваются сборщиком мусора, и в следствие память освобождается. а остаточные 90 мб - это "удалить на потом", т.к. у IE свой тупанутый сборщик мусора, который может очистить память, когда фаза луны соблаговолит - либо через секунду, либо через минуту.

а если собрать экземпляры в массив?

tenshi 07.04.2013 09:36

почему нет стирания XDR свойств?

devote 07.04.2013 11:22

Цитата:

Сообщение от tenshi
почему нет стирания XDR свойств?

а ты знаешь способ как это сделать в ИЕ

tenshi 07.04.2013 16:35

ну так через defineProperty не работает?

devote 07.04.2013 17:12

Цитата:

Сообщение от tenshi
ну так через defineProperty не работает?

ну если бы работало, не было бы фраз на тему того что там есть свойства. И при всем этом FINoM, дал ссылку на предыдущее обсуждение http://javascript.ru/forum/offtopic/...rty-v-ie8.html где именно эта проблема и обсуждалась


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