diff --git a/src/syscall/js/js.go b/src/syscall/js/js.go
index 5deef35c2bb36f5a780eb6a3df3cd4f2a131f476..336586ca2dd1831d9e695d2d5fb2d9fd5a172fd7 100644
--- a/src/syscall/js/js.go
+++ b/src/syscall/js/js.go
@@ -64,6 +64,9 @@ var (
 	valueGlobal    = predefValue(5)
 	memory         = predefValue(6) // WebAssembly linear memory
 	jsGo           = predefValue(7) // instance of the Go class in JavaScript
+
+	objectConstructor = valueGlobal.Get("Object")
+	arrayConstructor  = valueGlobal.Get("Array")
 )
 
 // Undefined returns the JavaScript value "undefined".
@@ -83,15 +86,17 @@ func Global() Value {
 
 // ValueOf returns x as a JavaScript value:
 //
-//  | Go                    | JavaScript            |
-//  | --------------------- | --------------------- |
-//  | js.Value              | [its value]           |
-//  | js.TypedArray         | [typed array]         |
-//  | js.Callback           | function              |
-//  | nil                   | null                  |
-//  | bool                  | boolean               |
-//  | integers and floats   | number                |
-//  | string                | string                |
+//  | Go                     | JavaScript             |
+//  | ---------------------- | ---------------------- |
+//  | js.Value               | [its value]            |
+//  | js.TypedArray          | typed array            |
+//  | js.Callback            | function               |
+//  | nil                    | null                   |
+//  | bool                   | boolean                |
+//  | integers and floats    | number                 |
+//  | string                 | string                 |
+//  | []interface{}          | new array              |
+//  | map[string]interface{} | new object             |
 func ValueOf(x interface{}) Value {
 	switch x := x.(type) {
 	case Value:
@@ -138,6 +143,18 @@ func ValueOf(x interface{}) Value {
 		return floatValue(x)
 	case string:
 		return makeValue(stringVal(x))
+	case []interface{}:
+		a := arrayConstructor.New(len(x))
+		for i, s := range x {
+			a.SetIndex(i, s)
+		}
+		return a
+	case map[string]interface{}:
+		o := objectConstructor.New()
+		for k, v := range x {
+			o.Set(k, v)
+		}
+		return o
 	default:
 		panic("ValueOf: invalid value")
 	}
diff --git a/src/syscall/js/js_test.go b/src/syscall/js/js_test.go
index 753e262d52e83f45c2073a124c1bf4a885c968c2..9cc931a31d38d99b3e465508fcc717410e555f70 100644
--- a/src/syscall/js/js_test.go
+++ b/src/syscall/js/js_test.go
@@ -254,6 +254,21 @@ func TestType(t *testing.T) {
 	}
 }
 
+type object = map[string]interface{}
+type array = []interface{}
+
+func TestValueOf(t *testing.T) {
+	a := js.ValueOf(array{0, array{0, 42, 0}, 0})
+	if got := a.Index(1).Index(1).Int(); got != 42 {
+		t.Errorf("got %v, want %v", got, 42)
+	}
+
+	o := js.ValueOf(object{"x": object{"y": 42}})
+	if got := o.Get("x").Get("y").Int(); got != 42 {
+		t.Errorf("got %v, want %v", got, 42)
+	}
+}
+
 func TestCallback(t *testing.T) {
 	c := make(chan struct{})
 	cb := js.NewCallback(func(args []js.Value) {