在 Dojo 中, dojo.hitch 函数非常重要. 原因有两点: 

Dojo.hitch在事件驱动的编程模型中十分有效,用户无需关心函数运行时上下文的变更,降低代码的耦合性。

dojo.hitch(null, handler, args) dojo.partial(handler, args) //这两者是等价的

每当一个函数被调用时,Javascript会创建一个对应的上下文。上下文创建步骤如下:

于this来说没有任何意义,因此会隐式转换为全局对象。

[html] var putValue = function(store, item, attr, value){ 
    return store.setValue(item, attr, value); 

… 
var myStore = new dojo.data.ItemWriteStore({…}); 
//dojo.partial返回了首个参数为myStore的putValue函数 
someObject.setValueHandler = dojo.partial(putValue, myStore); 
  
//等同于运行putValue(myStore, someItem, “foo”, “bar”) 
someObject.setValueHandler(someItem, “foo”, “bar”); 
var putValue = function(store, item, attr, value){
    return store.setValue(item, attr, value);
}

var myStore = new dojo.data.ItemWriteStore({…});
//dojo.partial返回了首个参数为myStore的putValue函数
someObject.setValueHandler = dojo.partial(putValue, myStore);
 
//等同于运行putValue(myStore, someItem, “foo”, “bar”)
someObject.setValueHandler(someItem, “foo”, “bar”);

var Student = {  college: "MIT",  getCollege: function() {   return this.college;  } }  function printCollege(foo) {  alert("College: " + foo()); }  printCollege(Student.getCollege); // "College: undefined", 即 this 的值为 GLOBAL

这里需要注意的是,dojo.partial并不锁定函数的运行时上下文。

函数上下文中 this 的确定规则如下:
函数上下文中this的值是函数调用者提供并且由当前调用表达式的形式而定的。
如果在调用括号()的左边,有引用类型的值,
那么this的值就会设置为该引用类型值的base对象。
所有其他情况下(非引用类型),this的值总是null。然而,由于null对

[javascript] var putValue = function(store, item, attr, value){ 
    return store.setValue(item, attr, value); 

var putValue = function(store, item, attr, value){
    return store.setValue(item, attr, value);
}
然而后来在应用需要与putValue有相似的功能但参数列表不同的函数,如下所示:

printCollege(dojo.hitch(Student, Student.getCollege)); // hitch 返回 function() {return Student.getCollege.apply(Student, arguments);} printCollege(dojo.hitch(Student, "getCollege")); // hitch 返回 function() {return getCollege.apply(Student, arguments);}

总结

当 dojo.hitch 的第一个参数省略的时候, 相当于把第一个参数设置为 null ,
这时 this 的值指的是 global 全局上下文.

Dojo.hitch是dojo提供的一个用来简化函数运行时上下文绑定的函数。简单来说dojo.hitch创建了一个绑定了上下文的新函数,用户可以不用担心心运行时的上下文变化会对函数产生影响。使用dojo.hitch也十分简单:

例 (函数不与定义它们的上下文即作用域绑定) :

还记得之前Javascript被调用时创建上下文的步骤吗?首先创建的就是arguments对象,arguments对象是一个函数的参数数组,以参数的传入顺序排列该数组内元素。

hitch 的中文意思是: 钩住,拴住. 在 Dojo 中, dojo.hitch()
的作用是给一个方法绑定其执行上下文.

在dojo工具包中,dojo/_base/lang模块对Javascript原生方法进行了包装或增强,提供了不少相当有用的方法。本文将介绍Javascript中的函数对象(Function)的基础知识,以及如何使用dojo.hitch绑定函数的上下文,另外还将介绍如何使用dojo.partial为函数绑定特定参数等实用技术。

正确的方法:

同时绑定运行时上下文和锁定参数

dojo.hitch 是在 Dojo 中直接或间接被广泛使用的函数.

 


当函数定义完成后,其函数签名就被固定下来。我们就不能增加或者删除非匿名的函数参数。有时候这限制了函数调用的灵活性,我们不得不重写新的函数来应付参数列表的变更,而dojo.partial方法打破了这个限制。

如果 dojo.hitch 的第一个参数 上下文 指定为 null, dojo
还提供了另外一个函数:

使用apply、call指定函数运行上下文

printCollege(function() {  return Student.getCollege(); }); // "College: MIT", this 的值被显示的指定为 Student

[html] someObject.setValueHandler = dojo.hitch(someObject, putValue,
myStore); 
 
//
putValue的首个参数被锁定为myStore,并且putValue中的this参数(如果有的话)指向someObject 
someObject.setValueHandler(someItem, “foo”, “bar”); 
someObject.setValueHandler = dojo.hitch(someObject, putValue, myStore);

  1. Javascript 中, 函数不与定义它们的上下文即作用域绑定

  2. 在 Dojo 中, 很多函数都用 hitch 的参数传递方式:
    第一个参数是上下文对象, 第二个参数是一个函数

[javascript] dojo.query(“.myNodes”).forEach(function(node){ 
    node.onclick = function(evt){ 
        return myObject.myHandler.call(myObject, evt); 
    }; 
}); 
dojo.query(“.myNodes”).forEach(function(node){
    node.onclick = function(evt){
        return myObject.myHandler.call(myObject, evt);
    };
});

当 dojo.hitch 有3个及以上参数的时候, 第三个开始往后的参数被用做
dojo.hitch 返回的匿名函数的参数传入

在本教程中,首先阐述了Javascript运行时上下文的基础,然后介绍如何使用dojo.hitch方法固定函数的运行时上下文,又了解了使用固定值锁定参数列表的方法-dojo.partial,最后介绍了使用dojo.hitch同时实现这两个功能。

版权声明:本文为博主原创文章,未经博主允许不得转载。

可以看到,无论外部运行时上下文如何变化,dojo.hitch保证函数myFunction的上下文对象始终是myObject。

为函数绑定上下文并返回函数是函数式编程的基础.

这里举一个例子:有一个object,这个object其中一个方法被当做多个HTML节点的点击事件的处理函数。下面是对应的代码。

function printsth(x, y, z) {  alert(x + y + z); }  var printArg = dojo.hitch(null, "printsth", "我是参数1", "我是参数2"); // 返回 function() {return printsth.apply( //     null, ["我是参数1", "我是参数2"].concat(arguments))}  printArg("这里的参数"); //相当于: printsth("我是参数1", "我是参数2", "这里的参数");

[javascript]  var myObject = { 
    foo: “bar”, 
    myHandler: function(evt){ 
        //  this is very contrived but will do.  
        alert(“The value of ‘foo’ is ” + this.foo); 
    } 
}; 
 
//  later on in the script:  
dojo.query(“.myNodes”).forEach(function(node){ 
    node.onclick = myObject.myHandler; 
}); 
        var myObject = {
            foo: “bar”,
            myHandler: function(evt){
                //  this is very contrived but will do.
                alert(“The value of ‘foo’ is ” + this.foo);
            }
        };
 
        //  later on in the script:
        dojo.query(“.myNodes”).forEach(function(node){
            node.onclick = myObject.myHandler;
        });
请看对应的Demo(http://dojotoolkit.org/documentation/tutorials/1.7/hitch/demo/demo.html)

用 dojo.hitch 再次改写上面的正确方法(有两种方式, 如下),
代码看上去简洁清晰了一些:

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图