Показать сообщение отдельно
  #1 (permalink)  
Старый 06.03.2012, 05:37
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

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>

Последний раз редактировалось devote, 08.03.2012 в 01:10.
Ответить с цитированием