Original: http://dojotoolkit.org/documentation/tutorials/1.10/hitch/index.html
Version: Dojo 1.10
For more To make good use of JavaScript native functions, the dojo/_base/lang module provides many very useful methods. Here, let’s learn the basics of JavaScript function (Function) object and how to use lang.hitch to bind the context of the function. On this basis, learn how to use lang.partial to bind specific parameters of a function, and how to use lang.hitch to achieve these two operations.
Before you start learning, you need to have a certain understanding of the basics of Dojo Toolkit, such as dojo/query, Dojo’s Array helpers, etc.
Before we understand how and when to use lang.hitch and lang.partial, we need to know what problems they solve. One of the most misunderstood concepts in JavaScript is: what is this? Usually, in object-oriented programming, when an object’s method is called, this points to this object. However, this is not the case in JavaScript. In order to better understand it, we must first understand the concept of execution context.
The execution context in JavaScript
In JavaScript, whenever a function is called, it is created The execution context. The steps to create this context are:
1) Create the arguments object;
2) Create the scrope object of the function;
3) Initialize the variables of the function; < /p>
4) Create this attribute.
The this attribute here is the most confusing place for developers. It is a reference to the context or scope object in which the function is called. Understanding this is the key to understanding how JavaScript works, because in JavaScript, the real context of a function execution is determined when the function is called.
Here is an example: If we have an object, a method in the object will be used as an event handler for some nodes in the document.
// Require the query resource, and wait until the DOM is readyrequire(['dojo/query','dojo/domReady !'], function(query) {var myObject = {foo: "bar", myHandler: function(e) {// This is very contrived but will do. alert("The value of'foo' is "+ this. foo);} }; // later on in the script: query('.myNodes').forEach(function(node) {node.onclick = myObject.myHandler; });});
When clicked With any DOM node of the’myNodes’ class, you might think that the above function definition will pop up a JavaScript alert box prompting “The value of’foo’ is bar”. However, because we set myObject.myHandler as the node click Event handler, we will get the prompt message “The value of’foo’ is undefined”. Look at the reason:
node.onclick = myObject.myHandler; This expression myObject.myHandler calls the myHandler function. In fact, the fact that the myHandler function is defined in the myObject object has been ignored Now node.onclick is a reference to the myHandler function. Note that this is only the function myHandler, not the context of myObject. The context in which the DOM event handler runs is the node that triggered the event, that is, regardless of where and how it is defined, this function is executed as a method of the node, and the result is inside the myHandler function during execution The this value is the node that currently triggers the event.
Note: If you find this confusing, keep one thing in mind: the root cause is because, like other non-basic types, Function objects are passed by reference, not by value.
Use the .apply and .call methods to change the execution context
Because the JavaScript function execution context is Determined when the function is called, it provides a way to change the context (ie this) through Function.apply and Function.call during execution. Very simple, both methods allow passing an object as the context of the execution function. For example, if you want to ensure that the handler in the above example is executed in the context of myObject, you can use the Function.call method to wrap our references, as follows:
query('.myNodes').forEach(function(node) {node.onclick = function(e) {myObject.myHandler.call(myObject, e); }});
In In most cases, the Function.apply method is used and the arguments object is passed from the external function. However, when the parameters of a function are known, it is recommended to use the call method, because when the JavaScript interpreter does not need to directly access the arguments object, slightly higher performance will be obtained.
Use lang.hitch to bind execution context
Dojo Toolkit provides a simple way lang.hitch binds the context of the function. Simply put, lang,hitch creates a Function object and binds it to a specific context, so that the function can be called safely without worrying about the change of the function context. Here is an example:
// `foo` is intentionally globalvar foo = "bar";require(['dojo/_base /lang'], function(lang) {var myFunction = function() {return this.foo; }; var myObject = {foo:'baz'}; // later on in your application var boundFunction = lang.hitch(myObject , myFunction); // test myFunction(); // "bar" boundFunction(); // "baz" myFunction(); // "bar"});
lang.hitch ensures a specific function, Bound to a specific execution context, no need to consider changes in the execution context when calling.
arguments object
The arguments object is an array-like object that saves the data passed to the current function parameter list. In addition, when the context is created, any named variables of the object have been created, so these values can be used inside the function, just like the variables of the current function itself. Remember, the arguments object is not a real Array object. Although it has many similarities with the Array object, it is read-only, which means that some other methods of the Array object cannot be used on the arguments object (such as Array. prototype.slice, etc.).
When a function is defined, the signature of the function is fixed, and named parameters cannot be added or deleted by any other method unless the function is redefined. This also brings a problem, especially when you need to use a function signature without actually copying or rewriting the original function. The Dojo Toolkit provides a simple way to implement this function-the lang.partial method.
Use lang.partial to change the parameter list of a function
A problem often encountered is that a function Multiple parameters are defined, but sometimes we only need some of them. For example, suppose we have a function with 4 parameters (taken from dojo/data):
var putValue = function(store, item, attr, value) {return store.setValue(item, attr, value);}
However, there may be a similar definition elsewhere in the item, with only 3 parameters:
someObject.setValueHandler = function(item, attr, value) {// placeholder function to be overriden};
Use lang.partial , You can create a new function with pre-set parameter values. In the above example, you can set the value of store in advance, and then set someObject.setValueHandler as a reference to part of the function, as follows:
p>
// assuming we have a dojo/data store called "myStore"// our functionvar putValue = function(store, item, attr, value) {return store.setValue(item, attr, value);}// ...// their function signaturesomeObject.setValueHandler = function(item, attr, value) {// placeholder function to be overriden};//. ..// our solution using lang.partialsomeObject.setValueHandler = lang.partial(putValue, myStore);// ...// somewhere in the application when setValue Handler is invoked,// our putValue function will already have the "store" arg// set to a reference to "myStore"someObject.setValueHandler(someItem, "foo", "bar");
The explanation above :
1. First define a function with 4 parameters;
2. It is found that the setValueHandler function only needs 3 parameters, and we cannot modify it;
p>
3. We created a new function on the basis of putValue, and the value of the first parameter store of putValue is initially set to myStore;
4. The new part of the function is Only 3 parameters are passed during the call, but at this time the value of the first parameter of some functions has been set to myStore.
It should be noted that, unlike the lang.hitch method, lang.partial The execution context of the returned part of the function is not preset. In other words, the value of this may change depending on the new part of the function you use.
When using lang.partial, a parameter of the function represents the execution context. You can set a reference to an object as the execution context of the object, so that you can get the advantages of both at the same time.
Combine the advantages of hitch and partial
If you want to have the advantages of both hitch and partial, lang.hitch You can have both at the same time. You can add any number of values after the context and method names, and lang.hitch will use the predetermined context and preset parameter values to create a new function. As follows:
someObject.setValueHandler = lang.hitch(someObject, putValue, myStore);// .../ / later on in the application, the setHandler is invoked// again - this time in the context of someObjectsomeObject.setValueHandler(someItem,'foo','bar');
hitch and partial understand functional programming Basically, the Dojo Toolkit provides a lot of functional programming skills through the dojox/lang/functional namespace. It is recommended to take a look.
Summary
Here we review the JavaScript Function object-including the calling process of the function. Then lang.hitch was introduced, allowing you to bind the execution context of a function. On this basis, I learned how to use lang.partial to preset the parameter values of a function, and finally introduced how to use lang.hitch to bind at the same time. Set the context and parameter values.
Since lang.hitch allows pre-binding function execution context, it is very useful in event-driven programming techniques (or callback-based programming).