# JsObject constructor

JsObject(JsFunction constructor, [ List arguments ])

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);
    }