Вход

Просмотр полной версии : Вызов конструктора с массивом аргументов


FINoM
31.08.2012, 08:47
Пытаюсь сгенерировать конструктор, вызывающийся с массивом аргументов. Жаль для конструкторов нет функции, подобной apply. Вот, что получилось:

new (Function.prototype.bind.apply( function(){
console.log(this, arguments)
}, [{a:1},2,3,4]));

{a: 1}, по идее должен быть контекстом, но в консоли выдаётся пустой объект. В общем, как, имея массив аргументов, вызвать конструктор?

devote
31.08.2012, 09:23
Мы это в скайпе разве не обсуждали?

Aetae
31.08.2012, 09:52
http://stackoverflow.com/questions/1606797/use-of-apply-with-new-operator-is-this-possible
Много интересных вариантов, не только первый.

Ну и всегда есть кондовый eval, если нужно быстро наговнокодить и не напрягать голову.)

nerv_
31.08.2012, 12:53
{a: 1}, по идее должен быть контекстом
вроде бы контекст для конструктора Function указать нельзя...

Aetae
31.08.2012, 13:00
вроде бы контекст для конструктора Function указать нельзя...
Ещёбы. Этож бред. Просто вдумайтесь. Сам смысл new теряется.

nerv_
31.08.2012, 13:04
В общем, как, имея массив аргументов, вызвать конструктор?
создать функцию и передать массив аргументов ) Или Я не догоняю? :)
var arr = [ 'x', 'y', 'z' ];
var fn = new Function( arr.join(),
'return ' + arr.join( '+' ) );

alert( fn.apply( null, [ 1, 2, 3 ] ) );

FINoM
01.09.2012, 00:04
Мы это в скайпе разве не обсуждали?Нет, решение не подошло.создать функцию и передать массив аргументов ) Или Я не догоняю?
Во, сделал:
Function.prototype.applyConstruct = function() {
var length = arguments.length,
argNames = [];
for( var i = 0; i < length; i++ ) {
argNames.push( 'arg' + i );
}
argNames.join( ',' );

return new Function( argNames, 'return new this( ' + argNames + ' );' ).apply( this, arguments );
}
F = function() { this.a = 1; console.log( this, arguments )};
F.applyConstruct( 1,2,3,4,5 );

devote
01.09.2012, 00:52
Во, сделал:
хм а чем не годится такой вариант:
Function.prototype.applyConstruct = function() {
var F = function() {}
F.prototype = this.prototype;
return this.apply( new F, arguments );
}

F = function() { this.a = 1; console.log( this, arguments )};
F.applyConstruct( 1,2,3,4,5 ); может я что-то не понимаю и тебе что-то надо другое?

FINoM
01.09.2012, 00:58
может я что-то не понимаю и тебе что-то надо другое?Не хочу лишний раз вызывать конструктор с new.
this.apply( new F, arguments ); new F запускается без аргументов, что чревато ошибками, если аргументы обязательны.

devote
01.09.2012, 01:02
new F запускается без аргументов, что чревато ошибками, если аргументы обязательны.
да где??? Я же создал функцию обертку, она всегда будет без аргументов... Что-то ты либо совсем не спишь, либо просто тупишь... Я же не вызываю оригинал через new, а вызываю пустую функцию, с прототипами оригинала.

FINoM
01.09.2012, 01:05
Да, тупанул.

FINoM
01.09.2012, 01:07
Хотя нет, стоп, а где ты передаешь массив?
UPD
Вижу, забыл добавит аргумент с массивом аргументов.

FINoM
01.09.2012, 01:18
Всё равно твоё решение херовое: возвращается экземпляр левого конструктора.

devote
01.09.2012, 01:29
ну да, я немного не дописал:
Function.prototype.applyConstruct = function() {
var F = function() {}
F.prototype = this.prototype;
this.apply( F = new F, arguments );
return F;
}

F = function() { this.a = 1; console.log( this, arguments )};
var a = F.applyConstruct( 1,2,3,4,5 );

alert( a instanceof F );

Gvozd
01.09.2012, 04:54
тему не читай
сразу отвечай

Разве не достаточно сделать конструктуру call/apply в контексте свежего чистенького объекта, который он и вернет уже оформив в виде своего объекта?

devote
01.09.2012, 05:05
Разве не достаточно сделать конструктуру call/apply в контексте свежего чистенького объекта
ну я ему в скайпе предлагал подобный вариант, но он его решил отвергнуть.

Aetae
01.09.2012, 05:56
тему не читай
сразу отвечай

Разве не достаточно сделать конструктуру call/apply в контексте свежего чистенького объекта, который он и вернет уже оформив в виде своего объекта?
Для этого конструкор должен быть специально подготовлен, с произвольным не пойдёт же.

devote
01.09.2012, 06:26
в скайпе ему, я предложил такой вариант:
function Foo( a, b, c ) {
this.lala1 = a;
this.lala2 = b;
this.lala3 = c;
}
var b = Object.create( Foo.prototype );
Foo.apply( b, [ 1, 2, 3 ] );

alert( [ b.lala1 ] );
alert( b instanceof Foo );

Aetae
01.09.2012, 06:33
Вообще Object.create как и bind не работают сами-знаете-в-чём.)

Aetae
01.09.2012, 09:10
подобные вещи вы можете невозбранно позаимствовать у мастерски созданной каким-то неизвестным гением чудо функции Class (http://javascript.ru/forum/offtopic/29508-klassy-v-javascript.html)

И ТУТ В ТРЕД ВРЫВАЕТСЯ ДЯДЯ ЛЕША:

Function.prototype.create = function ( args ) {
var Constructor = this;
function Wrapper() { Constructor.apply( this, args ) }
Wrapper.prototype = Constructor.prototype;
return new Wrapper
}


function Cat( a, b ) {
this.a = a;
this.b = b;
}

var cat = Cat.create( [1, 2] )

alert( cat.a ) // 1
alert( cat.constructor === Cat ) // true
alert( cat instanceof Cat ) // true
alert( cat.__proto__ === Cat.prototype ) // true


ну а совсем для эстетов можно делать обертку так, чтобы имя сохранялось )), так папа раньше делал в функции Class говорят, пока на него не наехали что это мыл долго)
var Wrapper = eval( '(function ' + this.name + '(){Constructor.apply(this,args)})' );


п.с. devote, че за хрень ты создал вообще))))? Я не пони как она работает, а, все пони, ты не дописал оказывается
Код с mdn (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply)
Function.prototype.construct = function (aArgs) {
var fConstructor = this, fNewConstr = function () { fConstructor.apply(this, aArgs); };
fNewConstr.prototype = fConstructor.prototype;
return new fNewConstr();
};

melky
01.09.2012, 10:45
п.с. как я понимаю это общеизвестные вещи к которым все рано или поздно приходят и гордится тут нечем?

ровно как и аналогичной функцией, которая была вконтакте.

... походу, каждый программист в своей жизни должен написать фреймворк, и написать функцию для создания классов.

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