Due to the rapid changes in version of JavaScript, the syntaxial forms and vocabulary are also updated in JavaScript, therefore it is seen that many of the JavaScript features are newer additions and may not necessarily be available in older browsers i.e. browsers running on older versions of JavaScript. Another problem is that some of the Browsers do not consider the newest features of JavaScript as safe due to the extreme power it is capable of showing, and hence they are not included or included as an experimental mode with limitations to restrict the usage. But why should we even discuss this? JavaScript is mainly used to develop client-side applications and the successful execution of the programs partially depend on the client’s machine i.e. the version of JavaScript available on the browser of the client.
Now the naive approach would be to run only those functionalities that can be run in the clients’ browser, though it’s really not a healthy approach. There are two primary techniques that a developer can use to “bring” the newer features of JavaScript to the older browsers namely Polyfilling and Transpiling.
Polyfilling
Polyfilling is an invented term by Remy Sharp. It is one of the methodologies that can be used as a sort of backward compatibility measurement. The definition is best given by Remy himself.
“A polyfill, or polyfiller, is a piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide natively. Flattening the API landscape if you will.”
— Remy Sharp
If we illustrate what he meant to say we will get that A polyfill or polyfiller is a code segment that is supposed to behave identically to a newer feature of JavaScript and still being able to run on older versions. For example, ES2015 provides a new utility Number.isNaN(…) to provide a secure and accurate method to check for NaN or Not a Number values. We can use polyfilling to replicate this behavior and use it on those pre-ES2015 browsers. The following snippet will be helpful in our case.
// Check if Number.isNaN already exists. // If False then proceed. if (!Number.isNaN) { // Define explicitly for older browsers. Number.isNaN = function isNaN(x) { // This is a property of NaN. // No two NaN can be equal to the other. // Because NaN is a concept not a comparable value. return x !== x; }; } |
We first check if the method is already available and prevent defining the explicit version if so. If not present then we are definitely on an older version of JavaScript so we explicitly define one using the property of NaNs that no two NaN is equal to each-other because NaN is a concept, not a comparable value to be equal to the other. Thus, we return True if they are not equals and otherwise we return False. This can be considered as one of the easiest polyfills.
Note: All the new features are not polyfillable or it is not possible always to create polyfills without any deviation thus while implementing polyfills explicitly it is recommended to have a knowledge of the working on whole. But, many developers prefer using the polyfills that are already available. Some of these are mentioned below.
Transpiling
New JavaScript versions also bring syntaxial updates as well which is not possible to be polyfilled as it would simply not get executed and instead will throw syntax errors in old JavaScript engines, this is where a transpiler comes into play. It has got its name from the union of two operation it performs Transformation + Compiling. In continuation, we can now define a “Transpiler” to be a tool that transforms code with newer syntax into older code equivalents and this process is called “Transpiling”.
By development practice, while using Transpiling it is essential to write the code maintaining the newer syntax but while deploying the project use a transpiler similar to a minifier or a linter to deploy the transpiled old syntax friendly program. That raises the question why should we even bother writing in the newer syntaxial form while still deploying the older one? This is a very logical question to ask and has a lot of good points to give as answers out of which few are given below.
- It goes without saying that the newer syntax was added to the language to make the code more readable and easily maintainable i.e. the newer versions are simply better than The older equivalents. Thus it is recommended to
write newer and cleaner syntax to achieve a better result. - Transpiling only for older browsers, while serving the newer syntax to the updated browsers, we can get the advantage of browser performance optimizations.
- Using the newer syntax earlier allows it to be tested more robustly in the real world, which provides earlier feedback and if found early enough, they can be changed/fixed before those language design mistakes become permanent. Thus using the newer syntax makes the syntax much more reliable in the long run.
Let us take some examples of Transpiling. ES2015 added a new syntaxial feature of default parameter value, it can be implemented using the following.
// Default Parameter Value Example. // If no parameter is passed a will be 5. function myFunc(a = 5) { console.log(a); } myFunc(96); // Logs 96. myFunc(); // Logs 5 as default. |
As you can see, if the parameter is not supplied we take the default parameter value in account but this syntax will not get recognized in pre-ES2015 engines. Thus after transpiling, we will get the older equivalent as the following.
// Default Parameter Value Example. // If no parameter is passed a will be 5. function myFunc() { // Using Ternary Operator to assign default // 5 if undefined. var a = (arguments[0] !== undefined) ? arguments[0] : 5; console.log(a); } myFunc(96); // Logs 96. myFunc(); // Logs 5 as default. |
As seen in the example above we can use a ternary operator to assign the default value if the argument is found to be undefined this will produce similar results to the ES6 equivalent. For next example let us see the thick arrow methods of ES6.
// Function Defining is now this easy. var myFunc = () => { console.log( "This is a function." ); } myFunc(); // This is a function. |
As you can see in the example above we can define a function without even using the keyword function and that also without hampering the readability, but this will not get recognized in pre-ES6 engines thus the equivalent code will be as following.
// Function Defining is now this easy. var myFunc = function () { console.log( "This is a function." ); } myFunc(); // This is a function. |
After learning about Transpilers it will be very odd to end this article without knowing some of the greatest of Transpilers available. The following is a small list of such tools.
Hopefully, we have covered enough to gain knowledge of what these methodologies are and why the use of both of them is not only important to the developer but also for the development of JavaScript itself.
Reference:
https://remysharp.com/2010/10/08/what-is-a-polyfill