JavaScript匿名函数知多少

深入探讨闭包函数的使用
服务器君一共花费了290.613 ms进行了6次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

在一些Javascript库中可以看见这种写法:

function(){
	//所有库代码代码
}();

这样写的一个目的是——封装。

JavaScript并不是面向对象的,所以它不支持封装。但是在不支持封装的语言里同样可以实现封装。而实现的方法就是匿名函数。

//定义
function F(x)
{
  	this.x = x;
  	function double(x){return x*x;}
  	this.getDoubleX = function(){
    	return double(this.x);
  	}
}
 
//使用
f = new F(12);
alert(f.getDoubleX());

上面的代码很简单,我没有去运行它。懂点js的都知道这是JS的类定义方式。函数F相当于一个构造函数,而函数里面的其他定义都是函数私有的外部无法访问,例如double函数。这样就变相实现了私有方法。其他打上“this.”前缀的成员相当于公开成员,外部可以访问。

而这些库之所以要用一个大函数包裹整个库代码,就是为了不向使用者暴露内部方法和变量,强制用户只能访问开放的API。从这一点可以开出这些开发者的良苦用心。

简单形式的封装调用:

var userName = function() { return "jeff wong" } ();  
alert(userName);  

上面的代码确实简单,我们可以逐步分解成下面的写法:

var anonymousFunc = function() { return "jeff wong" }; //匿名函数  
var name = anonymousFunc(); //执行该函数 返回人名  
alert(name);  

new一下Function的形式(大写Function)

var a = new Object();  
var b = new Function();  
//alert(typeof (a)); //object  
//alert(typeof (b)); //function  
alert(a); //[object Object]  
alert(b); //匿名函数  
//alert(a == b); //false  
//alert(a === b); //false  

正如你所看到的那样,我们new一个Object,变量a弹出的是[object Object],而new一个Function(注意,是大写Function),b在弹出的时候,生成了匿名函数。 既然b是匿名函数,函数当然可以执行,我们可以继续试试下面的代码验证自己的猜测:

alert(b()); //undefined  
alert(a()); //脚本错误 提示“缺少函数”  

new 一下function也大有乾坤(小写function)

简单的空函数:

var func = new function() { };  
alert(typeof (func)); //object  
alert(func); //[object Object]  
//alert(func()); //脚本错误 func不是函数  

其实上面的代码也就等价于下面的写法:

function anonymousClass() { } //匿名类  
var instance = new anonymousClass();  
alert(typeof (instance));//object  
alert(instance); //[object Object]  

函数带个返回值的,也不是很难理解

var func = new function() { return "jeff wong" };  
alert(typeof (func));  
alert(func);  
//alert(func()); //脚本错误 缺少函数  

其实上面的代码也就等价于下面的写法:

function anonymousClass() { return "jeff wong"; } //匿名类  
var instance = new anonymousClass();  
alert(typeof (instance));//object  
alert(instance); //[object Object]  

还是函数带个返回值的,写法稍微有点不同

下面的代码请注意和(2)中的区分一下,因为接下来要重点讨论的就是那一点点的不同书写形式:

var func = new function() { return new String("jeff wong"); };  
alert(typeof (func)); //object 意料之中  
alert(func); //这里?!  
//alert(func()); //脚本错误 缺少函数  

上面代码的等价形式依然简单:

function anonymousClass() { return new String("jeff wong"); }  
var instance = new anonymousClass();  
alert(typeof (instance));  
alert(instance);  

已经运行看到结果了吗?没错,第三种写法我们在弹出func或者instance的时候,都出人意料地得到了一段字符串"jeff wong"。细心比较(2)和(3)中的代码,除了return处的写法稍有不同之外,两处代码几乎完全一致,所以我们推断,毫无疑问,是new String的形式让我们的函数产生了意想不到的效果。 为什么会这样呢?

原来,在javascript中,只要在new表达式之后的constructor返回(return)一个原始类型(无return时其实是return原始类型undefined,如(1)),比如第(2)种写法,那么就返回new创建的匿名对象;而如果new表达式之后的constructor返回一个引用对象,比如对象(Object),函数(function)及数组(Array)等等,那么返回的该引用对象就将覆盖new创建的匿名对象。现在再来分析(3)中的写法,由于new String会构造一个字符串引用对象,它就覆盖了new所创建的匿名对象,而new String的所指向引用值是“jeff wong”,所以弹出的必然是当前new String所分配的值。

最后,留个思考题,大家看看下面的代码返回什么结果:

var func = new function() { var str = new String("jeff wong"); return str; };//再换种写法  
//alert(typeof (func)); //object 意料之中  
alert(func); //猜一下这里应该是什么结果?  

本文地址:http://www.nowamagic.net/librarys/veda/detail/548,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/548

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《Python在Unix和Linux系统管理中的应用》 Noab Gift (作者), Jeremy M.Jones (作者)

《Python在Unix和Linux系统管理中的应用(影印版)》作者们还构建了一个可以免费下载的Ubuntu虚拟机。该虚拟机包含了这《Python在Unix和Linux系统管理中的应用(影印版)》的源代码,还可以用来运行书中的实例,包括SNMP、IPython、SQLAlchemy和许多其他工具。《Python在Unix和Linux系统管理中的应用》展示了Python语言如何提供一种更加高效的方式来处理Unix和Linux服务器管理工作中的各种任务。《Python在Unix和Linux系统管理中的应用(影印版)》的每一章都会提出一个特定的管理问题,例如并发或数据备份,然后通过实际的例子提供基于Python的解决方案。

更多计算机宝库...