微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

Javascript之旅——第九站:吐槽function

2015-02-20 18:03 前端大全
点击上方蓝字↑↑↑,轻松关注哦~

说到funciton,也是我对js非常吐槽的一点,封装的让我眼瞎,马蛋的,哥只能大眼睁着去黑盒的使用,简直只有完完全全的听各类图书对function的道听图说,完全没有做到一点点的眼见为实。


一:function是什么


在很久很久以前,我们只知道function是一个函数,用C#的话来说就是一个方法,既然是方法嘛,肯定就是挂在类下面的,但是其实呢?


在js中函数就是对象,并不是我们惯性思维中的方法。何以为证呢?看代码。




从图中可以看到我声明了一个say函数,但是我很奇怪的看到,为什么say函数会有一些属性和方法呢?比如本该属于Object的toString,valueOf,constructor等等?然后比较好奇的去看看constructor到底是什么,可以看到其实是个Function构造函数,那这样我就非常清楚了,然来say只不过是Function对象的一个实例引用,知道了这个我就可以很轻松的把代码恢复如下:




二:看看function中一些属性和方法


现在我们知道了function其实就是一个对象,我们知道所有的引用类型都是继承自object,那为了好做比较,我定义了一个object的实例,接下来看看function中到底都有那些专属属性和方法。





可以看到,子类function确实还是有点自己的东西,那接下来就简单探讨下常用的属性和方法。


1. arguments属性


说到这个属性就特么的来气,就眼瞎,眼瞎的地方在于这个arguments属性里面其实做了很多很多的东西,以至于下面的一些奇怪现象可能会让你目瞪口呆!!!


<1>奇怪现象一:我的function中都没有形参,居然还能接受到实参的值。。。




<2>奇怪现象2:形参和实参传递并不统一,可以多传递,可以少传递,js都不会报错。




<3>奇怪现象3:形参和arguments居然可以做到同步,太神奇了。




上面的三个现象是不是让你觉得很奇怪???这些奇怪的现象是不是让你觉得Function中封装的太狠,因为他们做了很多操作,而你却只能大眼瞪小眼,啥也看不到。。。是不是非常遗憾呢???由于看不到源代码我也无能为力,只能根据书中的讲解以及自己的理解来领悟了。“高程3”中是这么说的,当调用function中传递的实参其实是给了Function构造函数中的一个”内部数组“,而arguments其实是对”内部数组“的高层封装,封装后的arguments不再是数组了,而是一个伪装的数组,之所以这么说是因为arguments还需要一个自己的独有属性callee,而这个callee保存的就是当前的对象say,所以只能把arguments做成对象,我可以让你眼见为实。




然后最诡异的一个问题就是形参能够和arguments实现数据同步,既然能够做到同步,我的第一个反应就是使用同一块内存地址,但是仔细想想他们怎么可能做到共享内存地址呢?但是再想想的话,arguments是对”内部数组“的封装,我就想这个name应该也是被做过手脚的,也就是说name其实也是对”内部数组“的封装,就像ECMA5中对字段提供get/set访问器一样,当然这是我的一种猜测,解释代码如下:



从上图中我们看到,当我对name进行赋值的时候,其实改变的是args这个数组的值,同理当我改变arguments的值时,其实也是修改”内部数组“的值,通过类似这种方法来达到我们上层看到的同步机制,画个简图如下:




2. length属性


如果你知道了上面的原理,那这个也好猜测,要么取得是正真的“内部数组”的length,要么就是取伪类arguments的length,反正最终都是”内部数组”的length,对不对,比较常用但是又没什么好说的。


3.prototype属性


这个也是Function内部做出来的一个属性,很有意思,我想大家也有耳闻,也不是三言两语能说得清楚的,准备放在下篇详细的讲讲。


4.caller属性


看这个名字大概也知道个一二,就是用来获取当前的父函数,不要小看这个caller哦,你有没有想过它可以实现C#中的stacktrace的功能呢?有时候我们记js日志就靠这玩意了,比如下面这样。




5:call,apply方法


因为这两个函数的功能都一样,只不过call方法必须逐一参数赋值,而apply必须传递数组,如果想眼见为实,可以看看它们在vs里面的代码提示,一切都明白了,所以我就放在一块说了,不过这鸟东西有什么好处呢?它最大的好处就是可以随便绑定对象,然后就可以实现对绑定对象动态新增方法和属性,可能说的有点抽象,看个例子就OK啦。




我们发现,本来我的obj只是一个空对象,通过apply之后,我的obj对象具有name和age属性了,是不是很神奇呢?


来自:一线码农的博客

链接:http://www.cnblogs.com/huangxincheng/p/4185934.html



/////////////////


1. 『前端大全』分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯,欢迎关注。微信号:FrontDev

(长按二维码↑↑↑自动可扫描)

http://web.jobbole.com/all-posts/

2. 点击“阅读原文”,查看更多前端文章。


 
前端大全 更多文章 5个典型的JavaScript面试题(上) Limu:JavaScript的那些书 Web开发:我希望得到的编程学习路线图 JavaScript基础工具清单 常用排序算法之JavaScript实现
猜您喜欢 Google征战VR的白日梦(DayDream) 七年iOS工作经验的我为什么放弃了iOS而选择了Android 移动端图片格式调研 腾讯产品经理成长经历感悟:成熟产品经理必备特质 R、Python、、到底该使用哪一种大数据编程语言?