能重写自己的函数

191 阅读3分钟

由于一个函数可以返回另一个函数,因此我们可以用新的函数来覆盖旧的。例如,在上一篇文章中我们提到的那个例子:

//例子:返回函数的函数
function a(){
    alert('A!');
    return function (){
        alert('B!');
    };
};

这时,我们也可以通过 a( ) 的返回值来重写 a( ) 函数自己:

a = a();

当前这句依然只会执行 alert('A!') ,但如果我们再次调用 a( ) ,它就会执行 alert('B!') 了。

这对于要执行某些一次性初始化工作的函数来说,会非常有用!这样一来,该函数可以在第一次被调用后重写自己,从而避免了每次调用时重复一些不必要的操作。


在上面的例子中,我们是在外面来重定义该函数的--即我们将函数返回值赋值给函数本身。但我们也可以让函数从内部重写自己。如:

function a(){
    alert('A!');
    a = function(){
        alert('B!')
    };
};

这样一来,当我们第一次调用该函数时会有以下情况发生:

  • alert('A!') 将会被执行(可以视之为一次性的准备操作)。
  • 全局变量 a  将会被重定义,并被赋予新的函数。

而如果该函数再被调用的话,被执行的就将是 alert('B!') 了。


下面,我们来看一个组合型的应用示例,其中有些技术我们将在未来的文章中谈论:

var a = (function(){
    function someSetup(){
        var setup = 'done';
    }
    function actualWork(){
        alert('Worky-worky');
    }
    someSetup();
    return actualWork;//返回的是该函数的引用,没有括号!
}());

在这个例子中有如下情况:

  • 我们使用了私有函数-- someSetup( ) 和 actualWork( ) 。
  • 我么也使用了即时函数-- 函数 a( ) 的定义后面有一对括号,因此它会执行自调。
  • 当该函数第一次被调用时,他会调用 someSetup( ) ,并返回函数变量 actualWork 的引用。请注意,返回值中是不带括号的,因此该结果仅仅是一个函数引用,并不会产生函数调用。
  • 由于这里的执行语句是以 var a = ... 开头的,因而该自调函数所返回的值会重新赋值给 a 。

现在我们可以尝试回答一下这个问题:上面的代码在以下情景中分别会 alert( ) 什么内容?

  1. 当它最初被载入时
  2. 之后再次调用 a( ) 时

这项技术对于某些浏览器相关操作会相当有用。因为在不同浏览器中,实现相同任务的方法可能是不同的。

我们都知道浏览器的特性不可能因为函数调用而发生任何改变,因此,最好的选择就是让函数根据其当前所在的浏览器来重定义自己。这就是所谓的“浏览器兼容性探讨”技术。

关于这方面的应用示例,我们会在后面的文章中给予展示。

本文摘自《JavaScript面向对象编程指南》,分享的目的仅供个人学习和理解,如需转载请备注本文出处,谢谢!