jQuery is considered harmful

Original author: Lea Verou
  • Transfer
Heh, I always wanted to write one of these “X is considered harmful” posts.

Before I begin, let me say the following: I believe jQuery had an incredible impact on the progress of the Web . He gave developers the opportunity to do things that were previously considered unthinkable. Forced browser manufacturers to implement many features natively (without jQuery, we probably would never have document.querySelectorAll). jQuery is still needed by those who cannot rely on modern buns and are forced to support relics like IE8 or worse.

However, no matter how I sympathize with these poor guys, they are in the minority. Today, there are already tons of developers who do not need to support old browsers with their scanty market share. And let's not forget those who are not professional developers: students and researchers, not only do they need all this cross-browser compatibility, often they don’t need anything at all except one single browser! You probably expect that in academia, everyone will enjoy using the newfangled buns of the Open Web Platform with pleasure? And not close, jQuery is just everywhere there. Why? Because jQuery is all that they know, they just have neither the strength nor the time to follow the latest web. They don't need a reason to use jQuery, it just has to be used. Despite this fact, and the ability to already do all these things natively,

Yes, most likely you do not need it ...


Definitely I'm not the first one who pays attention to the fact that almost everything that jQuery can do today also has native JavaScript. So I will not repeat myself and just give a few links:


Also, I will not waste time discussing the file size and how much faster the native methods work. This has already been chewed more than once. Today I want to pay attention to something else.

... but this is still not the reason to refuse to use it


To avoid extending the prototypes of native objects, jQuery uses its own wrappers on these objects. In the past, expanding native objects was considered a huge minus, and not so much because of potential conflicts with other extensions, but because of constant memory leaks in IE6. And so it has been since then, calling $ ('div') will return us not a link to an element or a list of nodes, but some jQuery object. This means that the jQuery object contains completely different methods than a normal link to a home element or a list of nodes.

Nevertheless, these links always come out in real projects. No matter how jQuery tries to ignore them, you still have to constantly operate on them, even if you simply wrap these links in $ (). For example, the callback context in the case of calling the jQuery .bind () method will be a reference to the home element, and not to the jQuery collection. It is also worth noting that you often use libraries from different sources, some of them need jQuery, and some not. All this leads to the fact that at the output we will find a hellish mixture of native house elements, lists of nodes and jQuery objects .

If the developer adheres to the naming convention for jQuery objects (adding $ in front of the variable name) and ordinary variables containing references to native elements, then this certainly alleviates the problem (although people tend to forget about any conventions, but suppose we live in an ideal world). Be that as it may, in most cases, the developers have never heard of such conventions, and as a result it is extremely difficult to understand strangers in their code. Each attempt to edit such code entails a lot of errors in the style of “Oh, damn it, this is not a jQuery object, forgot to wrap it in $ ()” or “Damn, right there it wasn’t the house element forgot to take it through $ (..) [ 0]. ” To avoid embarrassment, developers often end up starting to wrap everything in $ () at all, just in case. By reading the code after, you can see that the same variable is wrapped in $ () many times. For the same reason, it becomes very difficult to refactor this code so that it does not use jQuery. So in essence we geta hopeless situation .

Even if you strictly abide by the variable naming convention, a situation often arises when you need to call a native method for a home element or run a function from code that is not dependent on jQuery. And after some time, your code will already be packed from top to bottom by translating objects from jQuery to native ones and vice versa.

Suppose, after some time, you decide to add a couple more features for such a program, and in most cases you end up wrapping all the new links to the house elements and collections in $ () again. After all, you can’t always know exactly in which case you need this or that link. So again, it is a hopeless situation that also applies to all future code!

Take any random script with jQuery dependency and try to get rid of this dependency. They ran away. You will see that your main task is not to convert methods to native ones, but to understand what the hell is going on.

A pragmatic path to pure JS


Of course, today many libraries require jQuery, and as I recently tweeted , trying to completely get rid of it will look like some kind of digital veganism. And yet this does not mean that you need to continue to use it. Libraries can always be replaced in the future when their versions that do not use jQuery appear.

In addition, many libraries are written so that they do not require the presence of the variable $ as a synonym for jQuery. Just call jQuery.noConflict () to pick up the $ variable and find the best use for it. For example, I often use these helper functions, inspired by the Command Line API :

// Возвращаем первый элемент, который соответствует CSS селектору {expr}.
// Запросы могут быть ограничены потомками {container}-а
function $(expr, container) {
	return typeof expr === "string"? (container || document).querySelector(expr) : expr || null;
}
// Возвращаем все элементы которые соответствуют CSS селектору {expr} в виде массива.
// Запросы могут быть ограничены потомками {container}-а
function $$(expr, container) {
	return [].slice.call((container || document).querySelectorAll(expr));
}


In addition, I think that if you have to type jQuery every time instead of $, then you will think twice, do I really need it? IMHO of course.

Also, if you really like the jQuery API, but want to avoid bloating your code, consider using Zepto .

Only registered users can participate in the survey. Please come in.

Do you plan to abandon jQuery completely

  • 21.1% Yes 432
  • 66.4% No 1355
  • 12.3% Already refused 251

Also popular now: