| 网站首页 | 文章中心 | 设计欣赏 | 下载中心 | 设计咨讯 | 平面设计 | 二维|三维 | 网页制作 | NIIT论坛 | 酷站! | 
    您现在的位置: 卓越设计网 >> 网页制作 >> Javascript >> 网页制作正文
javascript中的作用域           
javascript中的作用域
作者:网站建设 文章来源:网页制作 点击数: 更新时间:2007-8-3 8:18:29

function addhandler() {
 var deep_thought = new BigComputer(42),
  the_button = document.getElementById('thebutton');

 the_button.onclick = deep_thought.ask_question.call(deep_thought);
}

代码之所以有问题的理由很简单:call立即执行了函数(译注:其实可以用一个匿名函数封装,例如the_button.onclick = function(){deep_thought.ask_question.call(deep_thought);},但比起即将讨论的bind来,依然不够优雅)。我们给onclcik处理函数一个函数执行后的结果而非函数的引用。所以我们需要利用另一个JavaScript特色,以解决这个问题。

.bind()之美

我并不是 Prototype JavaScript framework 的忠实粉丝,但我对它的总体代码质量印象深刻。具体而言,它为Function对象增加一个简洁的补充,对我管理函数呼叫执行后的上下文产生了极大的正面影响:bind跟call一样执行相同的常见任务,改变函数执行的上下文。不同之处在于bind返回的是函数引用可以备用,而不是call的立即执行而产生的最终结果。

如果需要简化一下bind函数以抓住概念的重点,我们可以先把它插进前面讨论的乘积例子中去,看它究竟是如何工作的。这是一个相当优雅的解决方案:

<script type="text/javascript">
 var first_object = {
  num: 42
 };
 var second_object = {
  num: 24
 };

 function multiply(mult) {
  return this.num * mult;
 }

 Function.prototype.bind = function(obj) {
  var method = this,
   temp = function() {
    return method.apply(obj, arguments);
   };

  return temp;
 }

 var first_multiply = multiply.bind(first_object);
 first_multiply(5); // 返回 42 * 5

 var second_multiply = multiply.bind(second_object);
 second_multiply(5); // 返回 24 * 5
</script>

首先,我们定义了first_object, second_object和multiply函数,一如既往。细心处理这些后,我们继续为Function对象的 prototype 定义一个bind方法,这样的话,我们程序里的函数都有一个bind方法可用。当执行multiply.bind(first_object)时,JavaScript为bind方法创建一个运行上下文,把this置为multiply函数的引用,并把第一个参数obj置为first_object的引用。目前为止,一切皆顺。

这个解决方案的真正天才之处在于method的创建,置为this的引用所指(即multiply函数自身)。当下一行的匿名函数被创建,method通过它的作用域链访问,obj亦然(不要在此使用this, 因为新创建的函数执行后,this会被新的、局部的上下文覆盖)。这个this的别名让apply执行multiply函数成为可能,而传递obj则确保上下文的正确。用计算机科学的话说,temp是一个 闭包(closure),它可以保证,需要在first_object的上下文中执行multiply,bind呼叫的最终返回可以用在任何的上下文中。

这才是前面说到的事件处理函数和setTimeout情形所真正需要的。以下代码完全解决了这些问题,绑定deep_thought.ask_question方法到deep_thought的上下文中,因此能在任何事件触发时都能正确运行:

function addhandler() {
 var deep_thought = new BigComputer(42),
  the_button = document.getElementById('thebutton');

 the_button.onclick = deep_thought.ask_question.bind(deep_thought);
}

上一页  [1] [2] [3] 


网页制作录入:as8130239    责任编辑:as8130239 
  • 上一篇网页制作:

  • 下一篇网页制作: 没有了
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网站
    导航
        最新图片
       推荐信息
       最 新 热 门
        最 新 推 荐
        相 关 文 章
    没有相关网页制作