class JS::Proxy

def method_missing(name, *args, &block)

def method_missing(name, *args, &block)
  js_name = to_js_name(name)
  unless existing_property?(js_name) || js_name.end_with?("=")
    raise NoMethodError, "undefined method `#{name}` for #{self}"
  end
  if js_name.end_with?("=")
    prop = js_name[0..-2]
    native[prop] = args.first
  else
    val = native[js_name]
    if `typeof val === 'function'`
      js_args = args.dup
      if block
        js_callback = %x{
          function() {
            let args = Array.prototype.slice.call(arguments);
            return #{block.call(self.class.new(`this`), *args)};
          }
        }
        js_args << js_callback
      end
      result = `val.apply(#{to_n}, #{js_args.to_n})`
      wrap_result(result)
    elsif `typeof val === 'object' && val !== null`
      wrap_result(val)
    else
      val
    end
  end
end