JsObject constructor
Constructs a new JavaScript object from constructor
and returns a proxy
to it.
Implementation
factory JsObject(JsFunction constructor, [List arguments]) {
var constr = _convertToJS(constructor);
if (arguments == null) {
return _wrapToDart(JS('', 'new #()', constr));
}
if (JS('bool', '# instanceof Array', arguments)) {
int argumentCount = JS('int', '#.length', arguments);
switch (argumentCount) {
case 0:
return _wrapToDart(JS('', 'new #()', constr));
case 1:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
return _wrapToDart(JS('', 'new #(#)', constr, arg0));
case 2:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
var arg1 = _convertToJS(JS('', '#[1]', arguments));
return _wrapToDart(JS('', 'new #(#, #)', constr, arg0, arg1));
case 3:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
var arg1 = _convertToJS(JS('', '#[1]', arguments));
var arg2 = _convertToJS(JS('', '#[2]', arguments));
return _wrapToDart(
JS('', 'new #(#, #, #)', constr, arg0, arg1, arg2));
case 4:
var arg0 = _convertToJS(JS('', '#[0]', arguments));
var arg1 = _convertToJS(JS('', '#[1]', arguments));
var arg2 = _convertToJS(JS('', '#[2]', arguments));
var arg3 = _convertToJS(JS('', '#[3]', arguments));
return _wrapToDart(
JS('', 'new #(#, #, #, #)', constr, arg0, arg1, arg2, arg3));
}
}
// The following code solves the problem of invoking a JavaScript
// constructor with an unknown number arguments.
// First bind the constructor to the argument list using bind.apply().
// The first argument to bind() is the binding of 'this', so add 'null' to
// the arguments list passed to apply().
// After that, use the JavaScript 'new' operator which overrides any binding
// of 'this' with the new instance.
var args = <dynamic>[null]..addAll(arguments.map(_convertToJS));
var factoryFunction = JS('', '#.bind.apply(#, #)', constr, constr, args);
// Without this line, calling factoryFunction as a constructor throws
JS('String', 'String(#)', factoryFunction);
// This could return an UnknownJavaScriptObject, or a native
// object for which there is an interceptor
var jsObj = JS('', 'new #()', factoryFunction);
return _wrapToDart(jsObj);
// TODO(sra): Investigate:
//
// var jsObj = JS('', 'Object.create(#.prototype)', constr);
// JS('', '#.apply(#, #)', constr, jsObj,
// []..addAll(arguments.map(_convertToJS)));
// return _wrapToDart(jsObj);
}