Comprendre la portée de la variable et la fonction, la classe dans la programmation est essentielle pour bien apprécier la façon dont vos variables d'interagir avec le reste de votre code source. Dans de nombreuses langues, mais cela peut être assez simple, mais JavaScriptâ € ™ s fonctions anonymes et gestion des événements, de même avec un peu de bizarreries, signifie que le traitement de votre portée JavaScript applications  peut devenir frustrant.
Cet article explique comment JavaScript gère la portée et la façon dont les différentes bibliothèques JavaScript fournir des méthodes pour faire face à ce problème et la façon dont ils aplanir quelques bosses. Weâ € ™ ll également se pencher sur la façon dont vous pouvez revenir à l'essentiel et de faire un peu la portée des querelles sans intérêt d'une bibliothèque, une démarche utile si youâ € ™ ré écriture du code qui a besoin pour fonctionner seul.
- Demo
- Agrandir
- Recharger
- New window
Gratuit iPage h�bergement Web pour la premi�re ann�e MOMENT
Si vous �tes toujours � la recherche d'un fournisseur d'h�bergement Web fiable avec des tarifs abordables, pourquoi vous ne prenez pas un peu de temps pour essayer iPage, seulement avec $1.89/month, inclus $500+ Cr�dits suppl�mentaires gratuites pour le paiement de 24 mois ($45)?
Plus de 1.000.000 de clients + existisng peuvent pas avoir tort, vraiment vous n'�tes pas aussi! Plus important encore, lorsque vous enregistrez l'h�bergement web � iPage gr�ce � notre lien, nous allons �tre heureux de renvoyer un plein remboursement. C'est g�nial! Vous devriez essayer iPage h�bergement web GRATUITEMENT maintenant! Et contactez-nous pour tout ce que vous devez savoir sur iPage.
Understanding scope in programming is key to appreciating how your variables interact with the rest of your code. In some languages, this can be quite straightforward, but JavaScript's anonymous functions and event handling features, along with a couple of little quirks, mean that handling scope in your applications can become frustrating.
This article discusses how JavaScript handles scope and how various JavaScript libraries provide methods for dealing with it and how they smooth out a few bumps. We'll also look at how you can get back to basics and do some interesting scope wrangling without a library, a useful approach if you're writing code that needs to stand alone.
You Are Here
So what is "scope"? We might say that it refers to your current location. If you run some JavaScript like...
var iAmGlobal = 5 * 5;
... then you're running in the global scope, the big wide world, where you can't go any further out. For something like...
function doSomething() { var inner = 5 * 5; };
... you're now boxed in by this function, running within its scope. The phrase "boxed in" is appropriate; take a look at this code:
var g = "global"; function go() { var l = "local"; } go(); alert(l); // throws a reference error
You'll see that when we run the go
function, the l
variable is contained within that function's scope. It cannot be accessed from a higher level scope.
How it Works
As well as variable scope, JavaScript uses the this
keyword to get a reference to the current execution context. That
rather terrifying term boils down this: at any point in your JavaScript
code, you can ask "Help! Where am I?" and get back an object reference.
This reference is for the current context, the object that "owns" the
currently executing code.
Now, you might think, given what we've just learned about scope, the owner of the current code would be the scope in which it is executed. After all, in JavaScript, even functions are objects and can be passed around in variables. But no. Take this function, for instance:
function go() { console.debug(this); } go();
This gives you a reference to the top-level execution context; in a browser, that's the browser window itself.
There are a few exceptions to this. For example, if we create a JavaScript object and then call a method on it, then the scope is bound to the object:
var myObject = { go: function() { console.debug(this); } }; myObject.go(); // console.debugs a reference to myObject
Similarly, when using functions as constructors, you see the same behavior:
function MyClass() { this.go = function() { console.debug(this); } } var instance1 = new MyClass(); var instance2 = new MyClass(); instance1.go(); // console.debugs a reference to the MyClass instance1 instance2.go(); // console.debugs a reference to the MyClass instance2
However, notice in this case that the reference is to the individual object instance rather than the class definition, which contrasts with the previous object literal example in which we will always receive a reference to the same object.
With event handlers, things get a little more confusing. If you specify an event handler inline in HTML, then you end up with it referencing the global window object. However, if you use JavaScript to wire your events, then you get a reference to the DOM object that raised it; for example, a click handler on a button would have the button element as the reference.
Event handlers are a common situation in which you would want to bind a function to a different scope; many JavaScript libraries provide features to help do just that. Let's take a look at some common options.
Libraries
Many developers use JavaScript libraries to avoid having to deal with browser inconsistencies and to take advantage of the many shortcuts they offer. Scope handling is something most libraries give a helping hand with, so let's take a look at what a few of the major players offer.
Prototype
Prototype comes with a bind method that allows a developer to specify the bound context for a function.
var products = ['Shoes', 'Sweater', 'Jeans', 'Wig']; function showCount() { for(var i = 0; i < number; i++) { document.body.innerHTML += this[i] + '. '; } } var fn = showCount.bind(products); fn(2); // outputs Shoes. Sweater. to the document
It also supports passing arguments that are "remembered" when you call the function, and these can be used to create shortcut functions; basically a version of a function that defaults to passing in certain arguments:
var showOne = showCount.bind(products, 1); var showFour = showCount.bind(products, 4); showOne(); // outputs Shoes. showFour(); // output Shoes. Sweater. Jeans. Wig.
See Prototype's Function.curry
for more information on this particular aspect of Function.bind
. The second useful feature of Prototype's scope handling is bindAsEventListener
. This is very similar to bind
but ensures that the first argument passed to the event handler is the event object.
Event.observe( $('showCountButton'), 'click', showCountHandler.bindAsEventListener(products, 2) );
Here we're using Prototype's event functions to set up an event listener when the showCountButton
is clicked. We're passing our products
array as the context, which the function is bound to, but in this case the showCountHandler
would look something like this:
function showCountHandler(e, number) { for(var i = 0; i < number; i++) { document.body.innerHTML += this[i] + '. '; } Event.stop(e); }
So we have the products
array as this
, but we also have the e
event object automatically passed as the first parameter, which we can later use to stop the default event.
The two Prototype methods for binding context are handy because they're used in exactly the same way, so you have a very simple and consistent method of taming your context.
Ext JS
Ext JS is farther reaching than either Prototype or MooTools in that it provides a full end-to-end framework for UI and application creation. This means it also provides correspondingly more features to control scope. To compare it with Prototype, let's look at how to bind to a particular context:
var fn = showCount.createDelegate(products, 4);
This is identical in usage to Prototype's bind method. But is there a difference when dealing with event handlers?
Ext.get('showCountButton').on('click', showCountHandler.createDelegate(products, 4) );
That's right: there is no difference. Ext JS will normalize the event object into an Ext.EventObject
for you and then append your additional arguments after that. However,
there are two caveats to this. First, Ext doesn't just pass the event
object to the handler, but also passes the source of the event (in this
case, the showCountButton
) and any options that were passed to the on
method. So, our handler now looks like this:
function showCountHandler(e, source, options, number) {}
However, there is a shortcut to using createDelegate
, and it involves understanding the arguments of the on
method. We can do this like so:
Ext.get('showCountButton').on('click', showCountHandler, products, { number: 4 });
The third argument of on
is the scope under which the handler should run, which eliminates the need to use createDelegate
. However, in order to pass further parameters, we have to use the options
parameter. So our handler in this case would be:
function showCountHandler(e, source, options) { number = options.number; }
This is not quite as elegant on the handler side of things, but it's useful to know that Ext JS provides a variety of methods for accomplishing similar things, and you can use them accordingly when building your applications.
MooTools
The MooTools library provides two methods that are essentially like replacements for Prototype versions: bind
and bindWithEvent
, a.k.a. bindAsEventListener
. However, on top of these familiar features, it provides a couple more that lend some extra flexibility. My favorite is Function.create
:
var fn = showCount.create({ bind: products, arguments: 4 });
This is nice and succinct, and to turn this into an event handler, we do this:
showCount.create({ bind: products, arguments: 4, event: true });
We can pass additional options, such as delay
, which defers the execution of the function by a specified number of milliseconds, and periodical
, which fires the function every time the specified interval elapses.
One library conspicuous in its absence is jQuery, which doesn't offer any context binding facility. But JavaScript does have built-in features that allow you to manage context in many scenarios, and it also provides relatively simple methods of building your own solutions to more complicated problems.
On Your Own
I'm no snob: leveraging the hard work of the great developers who have spent a lot of time on their libraries makes total sense. They will have worked through all of the bugs and edge cases so that you don't have to. On the other hand, understanding what's happening on the JavaScript level is important, not only as an academic exercise but also for those occasions when you can't rely on a library.
Sometimes offering standalone and library-independent scripts is best; for example, if you would like to make your code available publicly and for widespread use. By relying on a library, you restrict the use of the code to people who use that library.
Let's take a look at how scope and context can be handled without using a library.
Call and Apply
JavaScript functions have two methods available to them that are of particular interest for handling context. Let's look at call
:
showCount.call(products, 4);
Apply
is very similar but is used when you don't know
how many arguments you will be passing. It takes an array as its second
parameter:
showCount.apply(products, [4]);
Both of these achieve the same goal, but your usage case will determine which would work best for you.
Event Handler Scope
We saw in the explanations of scope how event handlers cause problems, and we also saw how the various JavaScript libraries provide means of getting around this. If you're stuck with bare-bones JavaScript, then you simply have to write your own means of scoping event handlers, and we'll look at how to do that now.
Call
and apply
trigger the function
immediately: that's not what we're after. Instead, we want to return a
new function, which will then be called when the event fires. So:
Function.prototype.bindContext = function() { // when adding functions using prototype, "this" is the // object which the new function was called on var callingFunction = this; // pass the desired scope object as the first arg var scope = arguments[0]; // create a new arguments array with the first arg removed var otherArgs = []; for(var i = 1; i < arguments.length; i++){ otherArgs.push(arguments[i]); } // return a function remembering to include the event return function(e) { // Add the event object to the arguments array otherArgs.push(e || window.event); // Array is in the wrong order so flip it otherArgs.reverse(); // Now use apply to set scope and arguments callingFunction.apply(scope, otherArgs); } }
This is a basic implementation with no error handling, but it provides a useful base to expand on and for understanding the overall approach. Dealing with event handler scope is essential for most JavaScript applications, and no developer should be tied to a single framework, so an appreciation for handling this problem at a low level is useful for every coder.
Conclusion
When building any large JavaScript application, a solid understanding of scope is not only useful but pretty much necessary. While using a common JavaScript library is a useful shortcut, it's certainly never bad to get back to basics and roll your own solution in order to gain more control of JavaScript scope.
Further Resources
- An introduction to scope in Dojo.
- A discussion of YUI that touches on scope within event handlers.
- Scope from a C# and object-oriented perspective.
- A huge technical reference on scope and closures in JavaScript.
- Interesting scope "gotcha."
- Sent (0)
- Nouveau
Générez vos vidéos d'entreprise par l'IA avec la voix ou simplement du texte
chatGPTaz.com
Parlez à ChatGPT dans votre langue maternelle
AppAIVidéo
Votre première application vidéo AI GRATUITE
Deepfake Video
Deepfake AI Video Maker
Deepfake
Deepfake AI Video Maker
AI Deep Fake
Deepfake AI Video Maker
AIvidio
AI Video Mobile Solutions
AIvideos
AI Video Platform & Solutions
AIvedio
AI Video App Maker
Artificial General Intelligence
Ai and higher level Artificial General Intelligence (AGI)
Artificial General Intelligence
Ai and higher level Artificial General Intelligence (AGI)
Faceswap AI en ligne
Échangez des visages, des vidéos, des photos et des GIF instantanément avec de puissants outils d'IA - Faceswap AI Online GRATUIT
Faceswap AI en ligne
Échangez des visages, des vidéos, des photos et des GIF instantanément avec de puissants outils d'IA - Faceswap AI Online GRATUIT
Faceswap AI en ligne
Échangez des visages, des vidéos, des photos et des GIF instantanément avec de puissants outils d'IA - Faceswap AI Online GRATUIT
Powerful AI Presentation PPT Maker for FREE
Build an impressive presentation with our free online AI presentation app
Your next top AI Assistant
Claude AI, developed by Anthropic
Your next top AI Assistant
Claude AI, developed by Anthropic
Temu gratuit 500 $ pour les nouveaux utilisateurs
Claim Free Temu $500 Credit via Affiliate & Influencer Program
Crédits publicitaires TikTok gratuits
Maîtrisez les publicités TikTok pour le marketing de votre entreprise
Dall-E-OpenAI.com
Générez automatiquement des images créatives avec l'IA
chatGPT4.win
Parlez à ChatGPT dans votre langue maternelle
Premier produit d'intelligence artificielle d'Elon Musk - Grok/UN.com
Parlez au chatbot Grok AI dans votre langue
Outily.win
Centre d'outils ouvert et gratuit, utilisable par tous et pour tous, avec des centaines d'outils
GateIO.gomymobi.com
Airdrops gratuits à réclamer et à partager jusqu'à 150 000 $ par projet
iPhoneKer.com
Économisez jusqu'à 630 $ à l'achat d'un nouvel iPhone 16
Acheter le robot Tesla Optimus
Commandez votre robot Tesla Bot : Optimus Gen 2 dès aujourd'hui pour moins de 20 000 $