You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<h3 id="webidl-dictionaries-interfaces-namespaces">Use WebIDL dictionaries, interfaces, and namespaces appropriately</h3>
1539
+
1540
+
Use the appropriate WebIDL mechanisms for new APIs.
1541
+
1542
+
WebIDL defines multiple constructs for defining Web APIs.
1543
+
Dictionaries, interfaces, and namespaces
1544
+
each have different properties suited to different purposes.
1545
+
1546
+
The goal is to ensure ergonomic, consistent APIs that feel natural to Web developers
1547
+
while avoiding pitfalls like "fake classes" or classes that provide no functionality.
1548
+
1549
+
<h4 id="dictionaries-for-configuration" class="no-num no-toc">Use Dictionaries for “Configuration” or “Input-Only” Data</h4>
1550
+
1551
+
Choose a dictionary when the part of the API represents data that is transient,
1552
+
especially when an API accepts a set of parameters, configuration, or options.
1553
+
1554
+
Dictionaries are ideal for when the data doesn't get stored or mutated; it's just used it at the time of the call.
1555
+
1556
+
For example, the [`ShareData`](https://www.w3.org/TR/web-share/#dom-sharedata) member from Web Share [[WEB-SHARE]]:
1557
+
1558
+
```WebIDL
1559
+
dictionary ShareData {
1560
+
USVString title;
1561
+
USVString text;
1562
+
USVString url;
1563
+
};
1564
+
```
1565
+
1566
+
And how it's commonly used:
1567
+
1568
+
<pre class="highlight">
1569
+
await navigator.share({text: "Text being shared" });
1570
+
</pre>
1571
+
1572
+
Dictionaries are easily extensible and makes it easy to add optional fields later as needed.
1573
+
Members of a dictionary are optional by default, but can be marked as `required` if needed.
1574
+
1575
+
Dictionaries are also highly idiomatic (i.e., natural to use in JavaScript).
1576
+
Passing `{ ... }` inline is the most natural way to supply configuration in JavaScript.
1577
+
1578
+
Dictionaries, because of how they are treated by user agents, are also relatively future-proof.
1579
+
Dictionary members that are not understood by an implementation are ignored.
1580
+
New members therefore can be added without breaking older code.
1581
+
1582
+
Dictionaries are best used for objects that don't need to be distinguished by type in their lifecycle (i.e., `instanceof` checks are mostly meaningless because it's always `Object`).
1583
+
1584
+
Dictionaries are "passed by value" to methods (i.e., they are copied).
1585
+
Browsers engines strip unknown members when converting from JavaScript objects to a WebIDL representation.
1586
+
This means that changing the value after it is passed into an API has no effect.
1587
+
1588
+
Again, taking the [`ShareData`](https://www.w3.org/TR/web-share/#dom-sharedata) dictionary as an example:
1589
+
1590
+
```JS
1591
+
const data = {
1592
+
"text": "Text being shared",
1593
+
// Ignored by a browser that does not include a "whatever" parameter.
1594
+
"whatever": 123,
1595
+
};
1596
+
let p = navigator.share(data);
1597
+
1598
+
// Changing this after calling .share() has no effect
1599
+
data.text = "New text";
1600
+
```
1601
+
1602
+
<h4 id="interface-for-functionality-state-identity" class="no-num no-toc">Choose an Interface for Functionality, State, and Identity</h4>
1603
+
1604
+
Interfaces are roughly equivalent to classes in JavaScript.
1605
+
Use an interface when a specification needs to bundle state--
1606
+
both visible properties and internal "slots"--
1607
+
with operations on that state (i.e., methods).
1608
+
1609
+
Unlike dictionaries, interfaces:
1610
+
1611
+
* can have instances with state,
1612
+
* can have need read-only properties,
1613
+
* can exhibit side-effects on assignment, and
1614
+
* provide the ability to check object's identity
1615
+
(i.e., one can check if it is an `instanceof` a particular class on the global scope),
1616
+
1617
+
Defining an interface also exposes it on the global scope, allowing for the specification of static methods.
1618
+
For example, the `canParse()` static method of the URL interface.
1619
+
1620
+
```JS
1621
+
if (URL.canParse(someURL)) {
1622
+
// Do stuff...
1623
+
}
1624
+
```
1625
+
1626
+
Give stateful interfaces a constructor, if possible.
1627
+
Do not add a constructor if a class has no state.
1628
+
Doing so is considered *bad practice*, as it is effectively creating a "fake class":
1629
+
that is, instances of the interface do nothing that a static method couldn't do.
1630
+
[`DOMParser`](https://html.spec.whatwg.org/#domparser) or [`DOMImplementation`](https://dom.spec.whatwg.org/#domimplementation) are examples of fake classes.
1631
+
1632
+
<h4 id="interface-serializer" class="no-num no-toc">Provide a serializer to make interface data more accessible</h4>
1633
+
1634
+
Add serializers to transform instances of an interface into a form that is expected to be used by many applications.
1635
+
1636
+
A `.toJSON()` method allows an instance of an interface to produce a useful JSON serialization.
1637
+
A `.toBlob()` method can be used to extract a binary representation of an interface.
1638
+
1639
+
This makes object natural to use with APIs.
1640
+
For example, [`GeolocationPosition`](https://www.w3.org/TR/geolocation/#dom-geolocationposition)
1641
+
provides a `toJSON()` method:
1642
+
1643
+
```JS
1644
+
const position = await new Promise((resolve, reject) => {
0 commit comments