Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Динамическое создание функции (https://javascript.ru/forum/misc/28413-dinamicheskoe-sozdanie-funkcii.html)

FINoM 18.05.2012 17:47

Динамическое создание функции
 
Пардон, туплю немного. Как создать динамическую функцию? Что я имею в виду:
Обычно функция из конструктора создаётся так:
new Function( 'a', 'b', 'return a+b' );

Нужно следующее:
['a','b','c','d','e', 'dosomething()']

Имея этот массив, нужно получить:
new Function( 'a','b','c','d','e', 'dosomething()' );

Или просто:
function( a, b, c, d, e ){ dosomething() }

Знаю, что нужно что-то сделать с apply или bind, но не знаю, что. Заранее благодарю.

FINoM 18.05.2012 17:50

Получилось, но выглядит не очень:
alert( new ( Function.bind.apply( Function, [ null, 'a','b','c','d','e', 'dosomething()' ] ) ) );
Буду рад более адекватным вариантам.

FINoM 18.05.2012 18:10

Мдэ, я молодец.
Maxmaxmахimus, спасибо.

FINoM 18.05.2012 18:56

Когда-то кто-то спрашивал, как сэмулировать оператор with:
function withEmu( object, f ) {
	var argumentNamesArray = [],
		argumentValuesArray = [],
		newF;                        
		for( var arg in object ) {
			argumentNamesArray.push( arg );
			argumentValuesArray.push( object[ arg ] );
			}
		argumentNamesArray.push( 'return (' + f + ')()' );
		newF = Function.apply( null, argumentNamesArray );
		return newF.apply( null, argumentValuesArray );
}

var x = withEmu( {a:1, b:2, c: 'blah'}, function() {
    return [a,b,c];
});

alert( x );

9xakep 18.05.2012 19:50

Хм...я правильно понимаю, что такое, например:
<div id='div'>123</div>
<script>
with(document.getElementById('div')) {
alert(innerHTML)
}
</script>

Твоя ф-ия сделать не сможет?

FINoM 18.05.2012 19:56

Ну почему же?
function withEmu( object, f ) {
	var argumentNamesArray = [],
		argumentValuesArray = [],
		newF;                        
		for( var arg in object ) {
			argumentNamesArray.push( arg );
			argumentValuesArray.push( object[ arg ] );
			}
		argumentNamesArray.push( 'return (' + f + ')()' );
		newF = Function.apply( null, argumentNamesArray );
		return newF.apply( null, argumentValuesArray );
}
var div = document.createElement('div');
div.innerHTML = 'valera'
var x = withEmu( div, function() {
    return innerHTML;
});

alert( x );


Только сеттер не будет срабатывать (innerHTML = 'valuev' → див не изменится)

9xakep 18.05.2012 20:05

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

9xakep 18.05.2012 21:08

Maxmaxmахimus,
щас уже не найду, я тогда еще даже не понимал, что такое объекты, и чем они отличаются

FINoM 18.05.2012 21:22

Цитата:

Сообщение от Maxmaxmахimus
БЛИН!!!! ВЫОХДИ ЗА МЕНЯ!!!!!!!!!!!!!!!!!!!!!!!

Не испытываю желания.
А зачем тебе эта функция, если не секрет?
(по реакции кажется, что она тебе очень нужна была)

FINoM 18.05.2012 22:12

Ничего не понял, но был рад помочь :)
А изолировать песочницу можно и фреймом, наверно.

melky 18.05.2012 22:27

FINoM, как работает функция? я то представляю, но хочу, чтобы создатель ф-и пояснил

Kolyaj 18.05.2012 22:29

Чужой произвольный код изолировать без ифрейма не получится.

FINoM 18.05.2012 22:36

Лень объяснять, лучше посмотри, как меняются переменные
function withEmu( object, f ) {
	var argumentNamesArray = [], // массив имен
	argumentValuesArray = [], // массив значений
	newF;                        
	for( var arg in object ) {
		argumentNamesArray.push( arg ); // "a", "b", "c"
		argumentValuesArray.push( object[ arg ] ); // "1",  "2", "blah"
	}
	argumentNamesArray.push( 'return (' + f + ')()' ); // "a", "b", "c", "return (function() {return [a,b,c];})()"
	newF = Function.apply( null, argumentNamesArray ); // то же самое, что и 
	//Function("a", "b", "c", "return (function() {return [a,b,c];})()") или
	//function(a,b,c){ return (function() {return [a,b,c];})() }
	return newF.apply( null, argumentValuesArray ); // вызываем её с аргументами "1",  "2", "blah"
}

var x = withEmu( {a:1, b:2, c: 'blah'}, function() {
    return [a,b,c];
});

alert( x );

Kolyaj 18.05.2012 22:40

Maxmaxmахimus,
я ничего не понял из того, что ты написал :)
Как запретить коду в песочнице обращаться к window?

Kolyaj 19.05.2012 09:21

var win = window;
with ({window: null}) {
    alert(win == window);
}
Да, перекрывается, но достучаться можно
var win = window;
with ({window: null, Function: null}) {
    new [].constructor.constructor('win', 'alert([this == win, window == win])')(win);
}

Kolyaj 19.05.2012 15:15

Цитата:

Сообщение от Maxmaxmахimus
нельзя, так как в оператор with передаетя проки, если у которого запросить что то через гет, то если возвращается обоект, то он оборачивает его в такое же прокси, если приметив, то оставляет. если гетится функция то она биндится к ну ты понял к чему), и естественно тоже оборачивается в проксиФанкшен.

Можно не рассуждения, а пример кода?


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