Shorthand Aliases
document.querySelector and addEventListener are verbose. JavaScript lets you alias them to anything. Here is what that looks like, and why knowing this matters even if you never use it.
One of the common objections to vanilla JavaScript is verbosity. document.querySelector, document.querySelectorAll, element.addEventListener -- these are long. If you write them hundreds of times, that adds up.
JavaScript is flexible enough to fix this. Understanding how shows you something true about the language, even if you never ship these patterns in production code.
The Essentials
- JavaScript allows any identifier for variables: Including
$and_, which is why jQuery used$and Lodash uses_. - You can alias DOM methods: A variable that holds a reference to a function is indistinguishable from calling that function directly.
- You can extend HTMLElement.prototype: Adding a method here makes it available on every DOM element in the page.
- This is a double-edged tool: Reduced verbosity comes at the cost of readability for other developers. Know the technique, but choose deliberately when to apply it.
Aliasing querySelector
jQuery's $ is famous. When JavaScript allowed $ as a valid identifier, a short selector function was the obvious use:
const $ = (selector, context = document) => context.querySelector(selector);
const $$ = (selector, context = document) => context.querySelectorAll(selector);
// Usage
const nav = $('nav');
const links = $$('.nav-link', nav);Two lines of setup, and now $ is a scoped querySelector and $$ is querySelectorAll. The actual DOM API underneath is unchanged.
You can extend this to event binding:
HTMLElement.prototype.on = function(event, handler, options) {
this.addEventListener(event, handler, options);
return this;
};
// Usage
$('button').on('click', () => console.log('clicked'));By adding on to HTMLElement.prototype, every DOM element in the page gains that method. The DOM API has not changed, just the surface syntax.
What This Actually Shows
At some point in a large vanilla JS project, patterns like these start to feel like building your own micro-library. That is exactly what you are doing.
The tweet that circulated in the JavaScript community put it plainly: every developer should build their own framework at some point. Not to ship it, but because the exercise forces you to understand what frameworks actually do. Most of what a framework provides at the API surface is exactly this: thin wrappers that make the underlying platform API more ergonomic.
Knowing you can do this gives you a useful perspective. When you look at how jQuery worked, or how React organizes its API, the underlying mechanism is often a variant of what you have just seen: take a browser API, give it a shorter name, add some default behavior, export it.
When to Actually Use This
For a solo project or a small team where everyone knows the conventions: reasonable. For a shared codebase or an open-source project: almost never. The verbosity of document.querySelector is a feature in unfamiliar codebases. Anyone reading vanilla JavaScript for the first time can look it up. A custom $ function requires them to find its definition first.
The project we are building will stay verbose. The browser APIs will be called by their full names. But knowing the shorthand is part of knowing the language.
Further Reading and Watching
- MDN: HTMLElement - The interface that all HTML elements inherit from. Adding methods here affects the whole page.
- MDN: Prototype chains - How JavaScript inheritance works, which explains why adding to a prototype affects all instances.
Video:
- JavaScript DOM Crash Course - Part 1 by Traversy Media. A solid foundation for the DOM APIs that aliasing builds on top of.