Incorrect titles for method/property articles

A long-standing issue with MDN is that it misleadingly uses static property and method syntax for instance properties and methods.

For example, there is an article titled SharedWorkerGlobalScope.close(), but if you type SharedWorkerGlobalScope.close in your console, it will print undefined. There is no close() static method on the SharedWorkerGlobalScope class. What this article is really referring to is the prototype method, SharedWorkerGlobalScope.prototype.close().

I could give hundreds of examples like this. A few, which I am not allowed to link to given the limitations on new users of this forum: WebSocket.protocol, Storage.setItem() (but localStorage.getItem()), Window.sessionStorage (but window.localStorage)…

This mistake isn’t universal. For example, the Array.prototype.forEach() article is correctly titled.

Is there a way we could en-masse fix all these incorrect article titles? And ideally any other cases where this incorrect syntax is used, e.g. in the body text. It would also be good to create some sort of style guide or policy to avoid this mistake from being repeated in the future.

As context, we are working on adding links from the HTML Standard to MDN. However, as one of the HTML Standard editors, I am not comfortable referring our readers to MDN given that MDN has such drastically misleading information prominently displayed in these articles’ titles.

1 Like

Yup, you’ve got us bang to rights here. This is a problem that we need to do something about.

I think the main reason that we’ve done nothing about it is that we’ve had very few complaints from readers about it, and in fact many people find the pages with titles of the form x.prototype.y confusing, especially beginners — they create an instance and then don’t understand that you then just need to type x.y. Yup, that’s a knowledge limitation, but there you go.

I’m going to take this seriously going forward, and work on putting together a plan of what to do here.

It would be easiest if we could just edit the titles, and not have to move the pages as well to the logical URL structure (x/prototype/y). Would that suffice?

That works for me! I do wonder about how it will work for things that have both static and prototype methods—just hope they don’t collide? Or do statics go under some x/static/y namespace?

We could do that, yes — for WebAPI stuff, static methods are a lot rarer than instance methods.

Thinking about it, we’d probably also want to change the wording on the pages to say “The x instance method of y”/“The x static method of y”, and also list the methods under headings of “Instance methods”/“Static methods” on the interface landing pages.

1 Like

I’ve started listing statics in their own section on overview pages, and that kind of thing. We do need to standardize how we handle them.

As for the page titles – I’m personally opposed to changing them. I know they’re technically wrong, but there are a few reasons I think they should stay as they are (or at least we need to do some serious research before changing anything):

  1. Not all accesses to these APIs are actually done through JavaScript. Many languages have DOM implementations, so including JavaScript-specific syntax in the page titles is going to complicate things.
  2. Users don’t generally search for “InterfaceName.prototype.someProperty”. Including the “.prototype” part is liable to complicate search unnecessarily.
  3. When you’re in the moment writing code, 99% of the time, this is how it looks. Given the complaints we get from users about the JS reference page titles including “.prototype”, I feel like changing the API docs might be a mistake.

I would actually instead suggest that we simply add text to the page title to describe what the API term refers to; this is something I would like to do anyway. For example:

  • Change “SharedWorkerGlobalScope” to “SharedWorkerGlobalScope interface” or even “SharedWorkerGlobalScope interface: globals available in shared workers”
  • Change “SharedWorkerGlobalScope.close()” to “SharedWorkerGlobalScope.close() method prototype”
  • Change “RTCPeerConnection.signalingState” to “RTCPeerConnection.signalingState property”
  • Change “RTCPeerConnection.ontrack” to “RTCPeerConnection.ontrack event handler”

Stuff like that.

They’re not just technically wrong; they’re actively misleading. X.y means something to web developers: it’s for static methods and properties. But these aren’t static methods and properties. You’re indicating to developers that there is a static close() method on SharedWorkerGlobalScope. But no such method exists.

This also speaks to your point about other languages. No matter what syntax other languages use for instance methods, it’s not going to be the same as the one they use for static methods. (I’ll leave aside the argument about whether the “MDN Web Docs” project should be catering to non-web languages in its documentation.)

I don’t understand your point about “when you’re in the moment writing code, 99% of the time this is how it looks”. That doesn’t ring true to me. When I’m in the moment writing code, it looks like self.close(), not SharedWorkerGlobalScope.close(). Or localStorage.getItem(), not Storage.getItem(). I don’t see how you could claim otherwise—the code you claim that it looks like, will in fact throw runtime exceptions!

I also would strongly object to using the term “interface”. That is a Web IDL-ism only relevant to spec writers and browser developers, and one we’re considering fixing in Web IDL since it’s so misleading (it’s derived from Java). “Class” is the correct concept.

Well, I meant of course that you write it as myWhatever.close(), not myWhatever.prototype.close(). :slight_smile:

Well, when we started writing this stuff, JavaScript did not have classes, and did not until very recently. “Objects” would have been inaccurate since we’re dealing with something more akin to types, so we decided long ago to use “interfaces;” it’s still technically accurate although I agree that we might want to revisit it – although as far as I’m aware these are still not implemented as actual JavaScript classes. Are they?

I would also say that saying InterfaceName.methodName() doesn’t imply a static method unless you think it does. to me, if the word “static” isn’t there, it’s not a static method.

All of this said, I agree we need to consider making changes. JavaScript has evolved a lot since we first decided how this stuff should be documented. There were no statics (or if there were, they sure weren’t being used). I never encountered a static in documentation work on MDN until about a year ago – and I’ve been doing this since 2006, including a couple of years as the sole staff writer pounding out vast amounts of content.

I would personally prefer to use the same format we currently do but with added information afterward, such as “SharedWorkerOrGlobalScope.someImaginaryStaticMethod() static method”, as the page title.

You talk about the fundamental nature of prototypes in JavaScript, and while I agree that that’s true, I’ll also point out that I’ve been pretty successful working with JavaScript, including some pretty substantial projects, without ever really paying any attention to the topic of prototypes at all. I still don’t really fully get what they are and how they work, since I’ve never really needed to know in order to get my work done. So I find it hard to believe that the everyday JavaScript programmer desperately needs to know this. :slight_smile:

1 Like

Sure, if you titled the article mySharedWorkerGlobalScope.close(), that would be more accurate :).

Not really true. It had classes, just not the class keyword.

It’s not; there is no such thing as an interface in JavaScript.

They are, and always have been.

It definitely does. For example of common statics, see e.g. Array.of(), Node.ELEMENT_NODE, or URL.createObjectURL(). You say ClassName.methodName() in those cases, and there it means what it says.

I don’t intend to talk about the fundamental nature of prototypes at all. Prototypes are the least important thing here. All I’m saying that I’m not willing to link from the HTML spec’s specification of SharedWorkerGlobalScope to a set of docs which says that a static SharedWorkerGlobalScope.close() method exists, when such a method does not in fact exist and trying to use it will give errors.

Maybe worth considering: change to adopting a convention of using a shorthand of the form Array#push for these cases.

See https://mathiasbynens.be/notes/javascript-prototype-notation

When writing (in text, not in JavaScript) about properties on specific prototypes, you may use the JavaScript notation, foo.prototype.bar . However, this shorter (non-JavaScript) notation is often used instead: foo#bar . Basically, the hash ( # ) stands for .prototype.

Advantages:

  • Array#push is shorter as a title than writing out Array.prototype.push. (Especially in cases like what we’re working on for the HTML spec annotations — where the MDN titles go into annotations in a 144px-wide margin — shorter is better.)
  • Array#push isn’t JavaScript syntax, so it can’t be misunderstood as being something that MDN readers should actually use in their JavaScript code. Instead it’s unambiguously just a documentation convention. (I’ll concede it may be confusing initially to readers when they first see it used in MDN, but I think readers would quickly get around any initial confusion about it.)
1 Like

Some variant of this debate has recurred over at least 10 years.

Script authors don’t – and don’t need to – understand the prototype model, in the large, and virtually everyone who goes to the String page wants to know what they can do with Strings, not what they can do with the String constructor.
– Mike Shaver, January 18, 2008

Generally, the decision has been made in favor of usability/findability over technical accuracy. However, the JS language reference pages do use “.prototype”. See String.prototype.charAt() and anything linked from the JS Reference sidebar.

@fscholz undoubtedly has an opinion supporting the choice made in the JS reference; he’s currently out at a conference.

I’ve actually argued repeatedly that we should restore the String pages to being just String.charAt() and so forth, because I agree with Shaver’s argument from 10 years ago (I actually literally remember that post and that conversation, because it was a big one at the time).

1 Like

We could look into some alternative title formats. After all, part of the SEO project is going to want to look into adding more to these titles anyway.

For instance, we could try titles like one of the below:

  • SharedWorkerOrGlobalScope: close() method
  • close() method (SharedWorkerOrGlobalScope)
  • SharedWorkerOrGlobalScope close() method: Terminate a shared worker’s scope
  • The SharedWorkerOrGlobalScope class’s close() method
  • close() method (SharedWorkerOrGlobalScope class member) [or something worded with prototype if you insist :slight_smile:]

There are plenty of possible permutations; if we can find one we like, it could solve multiple problems with one shot.

A certain popular site with high search rankings, which shall remain nameless, uses the title format “JavaScript String charAt() method”. Your third suggestion is similar but more detailed. Without the dot, there’s no direct implication that the method is a member of the class :smile:

I have written all this information up into a plan:

I’m intending to do some research and get some other opinions on what the best solution is. Feel free to comment.

1 Like

In a comment at https://docs.google.com/document/d/19ZJbG3tp7CBygsFCj0BeY9CPWCcvnv75GZeTKhGzSlQ/edit#, @domenic points out:

as the JavaScript private fields and methods proposal advances, Interface.#member will become valid syntax (note the .). Differing from valid syntax by just a . is probably pretty confusing.

So given that, I agree SharedWorkerGlobalScope#close() wouldn’t be ideal.

But I think what would work well is SharedWorkerOrGlobalScope: close() method (one of the possibilities in @sheppy’s list of alternatives below, and also in the Options for fixing titling of WebAPI reference pages proposal.

In the context like the annotations for the HTML spec margin, where space is limited, the build for the annotations could just drop the method part from the title that’s shown in the hypertext of the link to the MDN article… But in the context of the actual title of the MDN article itself, it seems like it would be better to include method in the title.

I like this option. It’s shorter but still clear. And as I noted in an earlier comment, in contexts where an even-shorter reference to the article would be useful, the method part could be elided from the reference.

So, an update. It looks like the most popular title suggestion is

InterfaceName: methodOrPropertyName (static) property/method

Examples:

  • SharedWorkerOrGlobalScope: close() method
  • URL: createObjectURL() static method
  • Window: location property
  • Notification: permission static property

I really like this too.

We also seem to like the “Other considerations” list:

  • On interface landing pages, make sure static properties and methods are listed separately in “Static properties”/“Static methods” sections. The prototype properties/methods can just be listed in “Properties”/“Methods” sections.
  • Update static property/method pages to include the word “static” clearly in the summary, e.g. “The Permission read-only static property of the Notification interface…” and “The createObjectURL() static method of the URL interface…”.
  • If a situation arises where instance and static members collide (i.e. are called the same thing), add a disambiguation suffix to each slug, e.g. /x_prototype and /x_static, and a disambiguation page at /x.
  • This should all be done for the JS built-in reference pages too. Let’s make everything consistent.

Future work:

  • Investigate changing all instances of “interface” on MDN to “class” — “interface” is a historic WebIDL thing, but it conceptually wrong, and we seem to be moving towards “class”. The naming of ES2015 classes would support this too. This would need to be done carefully, and would take a bit of effort to make sure it is done across the whole site.

Before we do any of this, I am intending to do some further research and user testing.

2 Likes

We have to be sure that macros like domxref and sidebars will continue to work after sny changement in slugs or titles.

I do think they will need to be updated, which will put constraints on the transition.

1 Like

Yup, there will definitely be some work needed here.

I can put significant time into helping with all the work needed.

It’s enlightened self-interest for me, because there are on the order of 350 MDN articles for methods and properties defined in the HTML spec that potentially need to be changed — and the HTML editors would really prefer to see those changed before landing my patch that adds annotations to the HTML spec for all those MDN articles.