What's best practice for read-only access to JS object properties?

52 views
Skip to first unread message

Jonathan Hall

unread,
Jul 11, 2016, 4:36:37 PM7/11/16
to GopherJS
Suppose I'm writing GopherJS bindings around a JS object with read-only properties. What should be considered best practice here?

Using the File API as a simple example of a JS object with read-only properties (see https://developer.mozilla.org/en-US/docs/Web/API/File), I could do either of the following for the 'name' parameter:

    type File struct {
        js.Object
        Name string `js:"name"`
    }

Or...

    type File struct {
        js.Object
    }

    func (f *File) Name() string {
        return f.Get("name").String()
    }


The former seems cleaner. It's certainly more concise, and seems a closer mapping of the JS concept to Go.  But it does mean that if someone attempted to set the read-only parameter, it would cause a JavaScript exception, outside the control of GopherJS. Of course GopherJS could still recover it, but as far as I know, simply setting a value should never cause a panic in a normal Go program.

What do others think?

Jonathan Hall

unread,
Jul 12, 2016, 2:27:18 PM7/12/16
to GopherJS
Pending further discussion, I decided to look at existing GopherJS bindings for any precedent, and I see that my first option is used in several cases.  I'd still like to hear whether this was an intentional decision, and whether it is considered best practice.

A few places where I found read-only values exposed using js tags:


I'm sure there are others.

Dmitri Shuralyov

unread,
Jul 16, 2016, 12:46:53 PM7/16/16
to GopherJS
This is a great question. I haven't thought in much detail about this before.

I would probably still go with with exposing it as fields, and document that they're read only. It's definitely an alien concept to Go programs.

The reason to use a variable for me is mostly because it's shorter, simpler code. Also, func calls tend to appear more "expensive" since it's hard to know how much computation is done to return the answer, so I'd be tempted to do this silly thing:

name := f.Name()

Where f.Name() is implemented as return f.Get("name").String().

The reason using a variable should be okay is because:

a) it's can/should be documented as read-only
b) people using it should be familiar with the JS equivalent and not expect the Go wrapper to do something different
c) no reasonable code would try to change it, again, because it'd go against the Go (documented as read-only) and JS (documented as read-only) APIs

It's still unsafe, but it's as unsafe as dereferencing a nil pointer. Don't do it, and your program won't panic. But you can't stop someone from doing it on purpose.
Reply all
Reply to author
Forward
0 new messages