javascriptecmascript-6webidl

Why isn't setting attribute to an invalid value throwing?


As defined per WebIDL specification, setting attribute on an interface should convert the JS value to its IDL equivalent. It is explicitly stated that if the value cannot be converted it should throw a TypeError.

But why isn't this throwing, but instead just failing silently?

document.onvisibilitychange = 4;
console.log(document.onvisibilitychange); // null

Solution

  • The IDL definition of Document#onvisibilitychange is

    attribute EventHandler onvisibilitychange;
    

    EventHandler being itself defined as

    [LegacyTreatNonObjectAsNull]
    callback EventHandlerNonNull = any (Event event);
    typedef EventHandlerNonNull? EventHandler;
    

    Where LegacyTreatNonObjectAsNull is:

    If the [LegacyTreatNonObjectAsNull] extended attribute appears on a callback function, then it indicates that any value assigned to an attribute whose type is a nullable callback function will be converted more loosely: if the value is not an object, it will be converted to null, and if the value is not callable, it will be converted to a callback function value that does nothing when called.

    Here the value is not an object, and thus it's treated as null. No error is thrown.


    Other stricter attributes would throw, e.g. an <input>'s files attribute, which is defined as

    attribute FileList? files;
    

    will throw if you set it to anything but a FileList object:

    document.querySelector("input").files = 0;
    <input>