Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   Object.predefinedProperties создает новый объект с назначенными getter'ами/setter'ами (https://javascript.ru/forum/project/26364-object-predefinedproperties-sozdaet-novyjj-obekt-s-naznachennymi-getter%27ami-setter%27ami.html)

devote 06.03.2012 05:37

Object.predefinedProperties создает новый объект с назначенными getter'ами/setter'ами
 
Мне тут понадобилась такая функция, а точнее возможность создать getter's/setter's в новых объектах. Пришлось написать, работает во всех браузерах. Если кому надо пользуйтесь на здоровье, сильно не бейте за ошибки, возможно они там и есть, пока сам не вижу :) потом глядишь и увижу. Вторым параметром объект из которого будут скопированы сыойства( не обязательный параметр )
Object.predefinedProperties = function( props, from ) {

	var tmp = {}, vb = false;

	from = from || {};

	if ( Object.defineProperties ) {
		Object.defineProperties( tmp, props );
	} else if ( Object.defineProperty ) {
		try {
			for( var key in props ) {
				Object.defineProperty( tmp, key, props[ key ] );
			}
		} catch( _e_ ) { // IE8 defineProperty fails if not HTMLElement
			vb = true;
		}
	} else if ( tmp.__defineSetter__ && tmp.__defineGetter__ ) {
		for( var key in props ) {
			tmp.__defineSetter__( key, props[ key ].set );
			tmp.__defineGetter__( key, props[ key ].get );
		}
	} else vb = true;

	if ( vb ) {
		if ( !( "pdo_exec_vb_global" in window ) ) {
			execScript('Function pdo_exec_vb_global(code) ExecuteGlobal(code) End Function', 'vbscript');
		}
		window[ "pdoCache__" ] = window[ "pdoCache__" ] || { inc: 0 };

		var pdoname = "pdo__" + pdoCache__.inc++,
			parts = [ "Class " + pdoname ];

		for( var key in from ) {
			parts.push( "Public " + key );
		}

		pdoCache__[ pdoname ] = {};

		for( var key in props ) {
			window[ "pdoCache__" ][ pdoname ][ key ] = {
				set: function( key ) { return function( me, val ) { props[ key ].set.call( me, val ) } }( key ),
				get: function( key ) { return function( me ) { return props[ key ].get.call( me ) } }( key )
			}
			parts.push(
				"Public Property Let " + key + "(val)",
				"Call pdoCache__." + pdoname + "." + key + ".set(me,val)",
				"End Property",
				"Public Property Get " + key,
				"Set " + key + " = pdoCache__." + pdoname + "." + key + ".get(me)",
				"End Property"
			);
		}

		parts.push(
			"End Class",
			"Function " + pdoname + "f()",
			"Set " + pdoname + "f=New " + pdoname,
			"End Function"
		);

		pdo_exec_vb_global( parts.join( "\n" ) );

		tmp = window[ pdoname + "f" ]();
	}

	for( var key in from ) {
		if ( Object.prototype.toString.apply( from[ key ] ) === '[object Function]' ) {
			tmp[ key ] = function( key ) { return function() { return from[ key ].apply( tmp, arguments ) } }( key );
		} else {
			tmp[ key ] = from[ key ];
		}
	}
	return tmp;
}

Пример:
<!DOCTYPE html>
<html>
	<head>
		<script type="text/javascript">

			Object.predefinedProperties = function( props, from ) {

				var tmp = {}, vb = false;

				from = from || {};

				if ( Object.defineProperties ) {
					Object.defineProperties( tmp, props );
				} else if ( Object.defineProperty ) {
					try {
						for( var key in props ) {
							Object.defineProperty( tmp, key, props[ key ] );
						}
					} catch( _e_ ) { // IE8 defineProperty fails if not HTMLElement
						vb = true;
					}
				} else if ( tmp.__defineSetter__ && tmp.__defineGetter__ ) {
					for( var key in props ) {
						tmp.__defineSetter__( key, props[ key ].set );
						tmp.__defineGetter__( key, props[ key ].get );
					}
				} else vb = true;

				if ( vb ) {

					if ( !( "pdo_exec_vb_global" in window ) ) {
						execScript('Function pdo_exec_vb_global(code) ExecuteGlobal(code) End Function', 'vbscript');
					}

					window[ "pdoCache__" ] = window[ "pdoCache__" ] || { inc: 0 };

					var pdoname = "pdo__" + pdoCache__.inc++,
						parts = [ "Class " + pdoname ];

					for( var key in from ) {
						parts.push( "Public " + key );
					}

					pdoCache__[ pdoname ] = {};

					for( var key in props ) {
						window[ "pdoCache__" ][ pdoname ][ key ] = {
							set: function( key ) { return function( me, val ) { props[ key ].set.call( me, val ) } }( key ),
							get: function( key ) { return function( me ) { return props[ key ].get.call( me ) } }( key )
						}

						parts.push(
							"Public Property Let " + key + "(val)",
							"Call pdoCache__." + pdoname + "." + key + ".set(me,val)",
							"End Property",
							"Public Property Get " + key,
							"Set " + key + " = pdoCache__." + pdoname + "." + key + ".get(me)",
							"End Property"
						);
					}

					parts.push(
						"End Class",
						"Function " + pdoname + "f()",
						"Set " + pdoname + "f=New " + pdoname,
						"End Function"
					);

					pdo_exec_vb_global( parts.join( "\n" ) );

					tmp = window[ pdoname + "f" ]();
				}

				for( var key in from ) {
					if ( Object.prototype.toString.apply( from[ key ] ) === '[object Function]' ) {
						tmp[ key ] = function( key ) { return function() { return from[ key ].apply( tmp, arguments ) } }( key );
					} else {
						tmp[ key ] = from[ key ];
					}
				}
				return tmp;
			}

			var a = Object.predefinedProperties({
				testProp: {
					set: function( val ) {
						alert( "settable: " + val );
					},
					get: function() {
						return "Gettable Hello World!";
					}
				}
			});

			alert( a.testProp );

			a.testProp = "blah";


			var b = Object.predefinedProperties({
				testProp: {
					set: function( val ) {
						alert( "settable: " + val );
					},
					get: function() {
						return "Gettable Hello World!";
					}
				}
			}, {
				otherProp: 1,
				other2Prop: "blah test prop"
			});

			alert( b.testProp );

			b.testProp = "blah";

			alert( b.other2Prop );
			

		</script>
	</head>
	<body>
	</body>
</html>

B~Vladi 06.03.2012 14:14

Цитата:

Сообщение от devote
!window[ "pdo_exec_vb_global" ]

Содержимое этой ветки замени на:
execScript('Function pdo_exec_vb_global(code) ExecuteGlobal(code) End Function', 'vbscript');

devote 06.03.2012 15:40

Цитата:

Сообщение от B~Vladi (Сообщение 161677)
Содержимое этой ветки замени на:
execScript('Function pdo_exec_vb_global(code) ExecuteGlobal(code) End Function', 'vbscript');

Вот спасибо добрый человек :thanks:

B~Vladi 06.03.2012 15:48

Цитата:

Сообщение от devote
Вот спасибо добрый человек

Не за что. Ну и try/catch там не нужен совершенно.

devote 06.03.2012 17:11

Цитата:

Сообщение от B~Vladi
Ну и try/catch там не нужен совершенно.

А вот с этим я не соглашусь, ИЕ исключение выкидывает если идет попытка проверить существование объекта VB через JS

Тоесть если объект не существут, то все пройдет норм... Но вот если объект уже создавали, то выкинет исключение.

B~Vladi 06.03.2012 17:20

Цитата:

Сообщение от devote
Но вот если объект уже создавали, то выкинет исключение.

Ну так ты же проверяешь его существование в window.

devote 06.03.2012 17:31

Цитата:

Сообщение от B~Vladi
Ну так ты же проверяешь его существование в window.

Вот именно что при проверке он выкидывает исключение... тоесть любое не правильное обращение к объекту VB выкидывает исключение... Таков уж дэбильный VB

B~Vladi 06.03.2012 18:05

Цитата:

Сообщение от devote
Вот именно что при проверке он выкидывает исключение...

Попробуй так:
'name' in window

devote 06.03.2012 18:49

Цитата:

Сообщение от B~Vladi (Сообщение 161728)
Попробуй так:
'name' in window

Да прошло норм. СПС

devote 06.03.2012 19:18

Все переписал ее полностью... Долбаный VB не позволяет создавать динамически свойства в созданном классе, пришлось добавить второй параметр.

Не совсем все это удобно и идеально, но может вам и пригодится... Мне увы она не подошла для моих идей :( ( Гребаный VB )


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