未加星标

Modules in JavaScript

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏
javascript Modules

In JavaScript, there is a pattern you should be familiar with. That pattern is the module pattern. There are three main reasons why using this pattern or understanding where this pattern is used can be helpful and enable you to write better and more usable code.

Maintainability

Using the module pattern can help you to create code that is more maintainable. This is for the reason that writing your code into modules means that it should have fewer dependencies and writing an update to a module is only going to affect that module. This is often referred to as loosely coupled code in object-oriented design. Think of it as the ability to change the tire of a car without having to change the axle, or even worse the change the engine out.

Namespace Pollution

If you have ever run into global namespace collision you’ll understand why modules are helpful when creating an application. For instance, you have two different JavaScript files, and they both have a variable with the same name. If these variables are declared in a way where they become global, they can impact the other and variable values change. This applies to function and objects declared well if they both intercede into the global namespace. Modules are meant to allow a private namespace and lessen the likelihood of namespace pollution.

Reusability

Keeping your code dry (don’t repeat yourself) is not always easy. We’ve all been guilty of this one. ctrl + c and then a ctrl + v somewhere else. The issue with this is if you then later update your function or piece of code that you just copied, you have more than one place to update that now. Modules can help prevent this and allow you to reuse your code more easily.

Closure

You also need to understand the concept of closure to really understand how modules work. Much of this is done under the hood in the ES6 implementation of JavaScript and I will cover this next time in an ES6 module post, but I want to also show how things have been done not so long ago, as there is still a lot of value in this and will help you to better understand legacy code and also how things are done under the hood in ES6.

Closure is simply how objects and variable declared in relation to the surrounding curly brackets, or in other words their scope. For example, the following snippet of code is incrementing a variable declared outside of the increment function. This is perfectly valid code, just realize that counter is global in its scope.

Anonymous Function Pattern let counter = 0; // function to increment counter function increment() { counter += 1; return counter; } // increment() 3 times increment(); increment(); console.log(increment()); //3

So how would we abstract some of this away then so that our variables and functions are not global in scope? This can be done by using an anonymous function to bring about the closure and remove our variables from the global window scope.

(function () { let counter = 0; // function to increment counter function increment() { counter += 1; return counter; } // increment() 3 times increment(); increment(); console.log(increment()); //3 }()); Global Imports and Global Namespace

But what if we wanted to pass something into our anonymous function from the global namespace? This is often referred to as a global import. So in this example, we are simple incrementing a global variable and modifying it through our anonymous function. Not much of a difference you might be saying and in this case is true. However, this is a pattern that you’ll often see when loading a script and modifying or updating a global variable. Notice the ending callback function that is actually taking in our globalCounter variable. It then increments the globalCounter but limits the scope to our anonymous function. Following that we console.log(globalCounter) after the anonymous function has been called and returns us the initial value of 0 showing us that indeed the global variable was not modified.

let globalCounter = 0; (function (counter) { // function to increment counter function increment() { counter += 1; return counter; } // increment() 3 times increment(); increment(); console.log(increment()); //3 }(globalCounter )); console.log(globalCounter);//0 Object Interface and Revealing Module Pattern

These two patterns are very similar and it really depends on what type of access you want to allow access to your module. If you are familiar with object-oriented patterns and public and private access modifiers this is how you can simulate this in JavaScript. The following snippet has refactored out our counter to a useable object where we can call our increment function. We are directly accessing the object’s function to increment. There is something to be aware of though. Using this object interface will allow you to redefine the function later on. I can set counterModule.increment = undefined and change the behavior. This is a bit of a code smell.

let counterModule = (function () { let counter = 0; return { increment: function() { counter += 1; return counter; } } }()); counterModule.increment(); counterModule.increment(); counterModule.increment();//counter = 3

So what is the fix for preventing this type of dilemma? This is where using the revealing module pattern comes in. Notice that the code for our counterModule is almost the same snippet as above, the only difference is we are returning an object with its property bound to our function. This reveals only the code that we want to and can allow us to have private functions that we don’t necessarily want to reveal with the log() function for example. This is a roundabout way to have a private function on our counterModule

let counterModule = (function () { let counter = 0; function log(){ console.log('incrementing'); } function increment() { counter += 1; log(); return counter; } return { increment : increment } }()); counterModule.increment(); counterModule.increment(); counterModule.increment();//counter = 3 Libraries for Expediting your Modules and Dependencies

There are a few libraries out there AMD and CommonJS are some of the more popular that seeks to help out with writing your own modules, and I’d recommend using them when working on large applications. There are often times where a module you’ll have written can have a dependency and using these libraries assists with loading dependencies and helps to reduce some of the headaches of figuring out which where to place a dependencies script tag. If you’ve seen the module.exports = myModule or let myModule = require('myModule'); then you’re looking at commonJs loading of modules. AMD does things a little differently, and looks like this

define(['myModule', ], function(myModule) { console.log(myModule.increment()); });

As always, I hope you found this useful. I’ll be covering the ES6 implementation of modules in my next post so stay tuned.

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

分页:12
转载请注明
本文标题:Modules in JavaScript
本站链接:https://www.codesec.net/view/611859.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(12)