通过javascript的匿名函数来分析几段简单有趣的代码

 更新时间:2010年06月29日 01:19:19   作者:   我要评论

想起自己很久以前学习javascript的经历,也曾经碰到过几个由匿名函数造成的困扰(其中一个就是由闭包引起的),下面就整理几段简单代码讨论一下,让我们大家一起进步。
1、简单形式的封装调用
复制代码 代码如下:

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


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

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


2、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()); //脚本错误 提示“缺少函数”



3、new 一下function也大有乾坤(小写function)
(1)、简单的空函数
复制代码 代码如下:

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]

[code]

(2)、函数带个返回值的,也不是很难理解
[code]
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]


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

下面的代码请注意和(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); //猜一下这里应该是什么结果?

作者:Jeff Wong

相关文章

  • js实现向右横向滑出的二级菜单效果

    js实现向右横向滑出的二级菜单效果

    这篇文章主要介绍了js实现向右横向滑出的二级菜单效果,涉及javascript鼠标事件及页面元素的隐藏与显示实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • 拖动Html元素集合 Drag and Drop any item

    拖动Html元素集合 Drag and Drop any item

    拖动Html元素集合 Drag and Drop any item...
    2006-12-12
  • 常用原生JS兼容性写法汇总

    常用原生JS兼容性写法汇总

    这篇文章主要为大家详细汇总了常用原生JS兼容性写法,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • javascript 异步的innerHTML使用分析

    javascript 异步的innerHTML使用分析

    利用innerHTML代替createElement来动态添加网页内容已成为一种普遍的认识。但在商务应用,大数据的datagrid屡见不鲜,就算是innerHTML也捉襟见肘,于是人们又开发了分时加载的技术了(利用setTimeout)。
    2009-12-12
  • 为什么JS中eval处理JSON数据要加括号

    为什么JS中eval处理JSON数据要加括号

    这篇文章主要介绍了为什么JS中eval处理JSON数据要加括号的相关资料,需要的朋友可以参考下
    2015-04-04
  • Bootstrap table的使用方法

    Bootstrap table的使用方法

    这篇文章主要为大家详细解析了JS组件Bootstrap Table使用方法,具有一定的实用性和参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • 浅谈JS使用[ ]来访问对象属性

    浅谈JS使用[ ]来访问对象属性

    下面小编就为大家带来一篇浅谈JS使用[ ]来访问对象属性。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • 微信小程序 如何引入外部字体库iconfont的图标

    微信小程序 如何引入外部字体库iconfont的图标

    这篇文章主要为大家详细介绍了微信小程序引入外部字体库iconfont图标的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • React学习笔记之高阶组件应用

    React学习笔记之高阶组件应用

    这篇文章主要介绍了React 高阶组件应用,详细的介绍了什么是React高阶组件和具体使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • 原生JS实现前端本地文件上传

    原生JS实现前端本地文件上传

    这篇文章主要为大家详细介绍了原生JS实现前端本地文件上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-09-09

最新评论