We are often asked questions about technology in letters and messages - we are happy to answer. But in this case, the answer is one person, and he could be useful to many.
Therefore, we decided to analyze weekly on one issue, literally in five minutes.
Today, the question about the development of Sergey, our teacher Igor Alekseenko answers:
Mankipatching - why is it so bad or not so bad?
It is difficult to answer this question without starting a holivar. Mankipatching works, so you can’t say that it’s bad, but it’s important to remember that it’s very easy to shoot yourself in the foot.
Mankipatching is when we change the code in runtime, that is, as the program runs. For example, add non-existent methods to an array or override some global function.
Array.prototype.shuffle = function() { const i = this.length; while (i--) { fisherYatesShuffle(this, i); } }; [1, 2, 3].shuffle();
Mankipatching is ideal for one-time tasks when reverse engineering is needed. For example, if you need to debug a solution to the problem or once to collect some analytics, this will do, but these are obviously one-time approaches.
If we talk about industrial code, then carelessly handling monkey patches, you can break the work of the built-in objects that will be used throughout the program. Imagine that for some reason you have changed the behavior of the setTimeout function. Externally, it works the same way, but additionally this function solves some other tasks, for example, it stores the context.
const initNewTimeout = function() { const initialTimeout = window.setTimeout; window.setTimeout = function(fn, timeout, ctx) { initialTimeout(function() { fn.call(ctx); }, timeout); } }; initNewTimeout(); setTimeout(tickInContext, 100, this);
Of course, in your code, setTimeout will work as you need, but you cannot guarantee that everything else will work just as smoothly in other places where it is used. There are more extreme examples, for example, earlier in JavaScript it was possible to override even undefined and window.
It turns out that with monkey patching you need to be very careful and adhere to certain rules:
Adding a new one is better than changing the old one.
Changing the behavior of methods that are already built into the language is bad, because they can be used elsewhere besides your code. But to add something new than someone else would hardly think of to use is relatively safe. For example, add a method of mixing them into arrays. However, after some time, such a method may appear in the array - standards are developed, and browsers quickly pick them up.
Need to carefully test the patches.
This is a general advice for developers, but when it comes to monkey patches, you need to be doubly careful, because in one place they can help, and in another they can only be harmful. When writing monkipatches, you need to test not only the patch itself, but it would also be good to check if something broke at the level of the entire application.
It is better to use patches as temporary solutions.
Since monkeypatch can harm, they must be abandoned as soon as it becomes possible.
According to these rules, polyfiles are created - patches that add support for new features to old browsers. Agree how much the name changes its attitude to the approach. There were monkey corrections, and it became a universal filler. There were incomprehensible changes to the built-in objects, and there was a fix for problems supporting the new standards.
It seems that polyfiles are a good idea: you connect a polyfile and regardless of what browser the user has, you can use new things in the code, for example, Fetch for HTTP requests, Promise or Object.entries for iterating over objects.
<script src="./promise-polyfill.js"></script> <script src="./whatwg-fetch.js"></script> <script> fetch('/api/request') .then(resp => resp.json()) .then(json => render); </script>
But there are problems with this approach:
Something needs to be done with those browsers that already support what you are patching.
It would be ideal to disable patches for those browsers in which the feature is already supported. Usually, the developers of polyphiles take it upon themselves, but this point needs to be checked.
Compliance.
If we are talking about an already accepted standard that works in at least one browser and its support in the rest is just a matter of time, then there is no problem. But if we talk about the standard still under discussion, it is better not to create a polyfil, because programmers can start using it and get used to it, and standard developers will not be able to make any improvements to the standard, because the standard will be fixed de facto.
In such situations, it is better to use wrapper functions, which are sometimes called Ponifil . In principle, they allow you to do the same as polyfiles, but clearly. They also have no problems with standards: for example, the popular Lodash library grew out of a wrapper over non-working iterators in arrays. The guys added to the library forEach, map and other some, every, but they were not tied to the standard and therefore they had their hands untied from the beginning. Over time, they added other convenient methods for arrays and collections, such as shuffle, unique, flatten, and others. Despite the fact that iterators in arrays have been supported for a long time, Lodash is successfully developing.
// [1, 2, 3].map(it => it / 2); // arrayMap([1, 2, 3], it => it / 2);
Still, functions are easier to test. It is very difficult to test a polyfil completely. If you connect it in the same place where the tests are performed, your patch may change the code of the framework itself, which may affect the testing. And if you test the logic of polyfiles separately, it will be unclear whether they are connected correctly.
Even in different environments, your tests will work differently, because in some environments the patch will work, in others it will not. Ponifil has no such problems: you always know what you are testing, they connect and work clearly.
Is miscatching bad? Judging by the fact that it works, it is not so bad, but when using it you need to remember that it’s easier to break someone else’s code, it’s harder to test and you can forget that it is used.
Questions can be asked here .
Source: https://habr.com/ru/post/336312/
All Articles