不识function真面目【2】
来源:互联网 发布:皇室战争皇家巨人数据 编辑:程序博客网 时间:2024/05/01 04:41
Function是所有函数对象的基础,而Object则是所有对象(包括函数对象)的基础。在JavaScript中,任何一个对象都是Object的实例,因此,可以修改Object这个类型来让所有的对象具有一些通用的属性和方法,修改Object类型是通过prototype来完成的:
Object.prototype.myType = function () { console.log(typeof(this)); }; var arr = new Array; function add () { console.log("add"); } arr.myType(); //object add.myType(); //function
上面的代码为所有的对象添加了myType 方法,作用是返回该对象的类型。两条语句分别会显示“object”和“function”。
将函数作为参数传递【The function is passed as a parameter】
在前面已经介绍了函数对象本质,每个函数都被表示为一个特殊的对象,可以方便的将其赋值给一个变量,再通过这个变量名进行函数调用。作为一个变量,它可以以参数的形式传递给另一个函数,这在前面介绍JavaScript事件处理机制中已经看到过这样的用法
例如下面的程序将func1作为参数传递给func2:
function func1(theFunc){ theFunc(); } function func2(){ alert("ok"); } func1(func2);
在最后一条语句中,func2作为一个对象传递给了func1的形参theFunc,再由func1内部进行theFunc的调用。事实上,将函数作为参数传递,或者是将函数赋值给其他变量是所有事件机制的基础。
例如,如果需要在页面载入时进行一些初始化工作,可以先定义一个init的初始化函数,再通过window.onload=init;语句将其绑定到页面载入完成的事件。这里的init就是一个函数对象,它可以加入window的onload事件列表。
window.onload = init; function init () { console.log("hihi"); }
传递给函数的隐含参数:arguments 【The implicit parameter 】
当进行函数调用时,除了指定的参数外,还创建一个隐含的对象——arguments。arguments是一个类似数组但不是数组的对象,说它类似是因为它具有数组一样的访问性质,可以用arguments[index]这样的语法取值,拥有数组长度属性length。
arguments对象存储的是实际传递给函数的参数,而不局限于函数声明所定义的参数列表,例如:
function func(a,b){ alert(a); alert(b); for(var i=0;i<arguments.length;i++){ alert(arguments[i]); } } func(1,2,3);
代码运行时会依次显示:1,2,1,2,3。因此,在定义函数的时候,即使不指定参数列表,仍然可以通过arguments引用到所获得的参数,这给编程带来了很大的灵活性。arguments对象的另一个属性是callee,它表示对函数对象本身的引用,这有利于实现无名函数的递归或者保证函数的封装性
例如使用递归来计算1到n的自然数之和:
var sum=function(n){ if(1==n)return 1; else return n+sum(n-1); } alert(sum(100));
其中函数内部包含了对sum自身的调用,然而对于JavaScript来说,函数名仅仅是一个变量名,在函数内部调用sum即相当于调用一个全局变量,不能很好的体现出是调用自身,所以使用arguments.callee属性会是一个较好的办法:
var sum=function(n){ if(1==n)return 1; else return n+arguments.callee(n-1); } alert(sum(100));
callee属性并不是arguments不同于数组对象的惟一特征,下面的代码说明了arguments不是由Array类型创建:
Array.prototype.p1=1; alert(new Array().p1); function func(){ alert(arguments.p1); } func();
运行代码可以发现,第一个alert语句显示为1,即表示数组对象拥有属性p1,而func调用则显示为“undefined”,即p1不是arguments的属性,由此可见,arguments并不是一个数组对象。
函数的apply、call方法和length属性 【about the way and property 】
JavaScript为函数对象定义了两个方法:apply和call,它们的作用都是将函数绑定到另外一个对象上去运行,两者仅在定义参数的方式有所区别:
Function.prototype.apply(thisArg,argArray); Function.prototype.call(thisArg[,arg1[,arg2…]]);
从函数原型可以看到,第一个参数都被取名为thisArg,即所有函数内部的this指针都会被赋值为thisArg,这就实现了将函数作为另外一个对象的方法运行的目的。两个方法除了thisArg参数,都是为Function对象传递的参数。下面的代码说明了apply和call方法的工作方式:
//定义一个函数func1,具有属性age和方法mean function func1(){ this.age="15"; this.mean=function(arg){ alert( arg +" is " + this.age); } } //定义一个函数func2,具有属性age和方法meanfunction func2(){ this.age="25"; this.mean=function(arg){ alert( arg +" is " + this.age); } } var obj1=new func1(); var obj2=new func2(); obj1.mean("tom"); //tom is 15obj2.mean("jack"); // jack is 25obj1.mean.apply(obj2,["tom"]); // tom is 25obj2.mean.apply(obj1,["jack"]); // jack is 15obj1.mean.call(obj2,"tom"); // tom is 25obj2.mean.call(obj1,"jack"); // jack is 15
可以看出,obj1的方法A被绑定到obj2运行后,整个函数A的运行环境就转移到了obj2,即this指针指向了obj2。同样obj2的函数B也可以绑定到obj1对象去运行。【替换上下文环境】
代码的最后4行显示了apply和call函数参数形式的区别。
与arguments的length属性不同,函数对象还有一个属性length,它表示函数定义时所指定参数的个数,而非调用时实际传递的参数个数。例如下面的代码:
function sum(a,b){ return a+b; } alert(sum.length); //2function sum(a,b,c){ console.log(a+b); } sum(1,9) // 10alert(sum.length); //3
- 不识function真面目【2】
- 不识function真面目【1】
- js中的function(){}不好使
- 揭露黑客入侵真面目!
- [转贴]NET真面目
- ESB的真面目
- 流媒体的真面目
- ESB的真面目
- ESB的真面目
- ESB的真面目
- ESB的真面目
- ESB的真面目
- ESB的真面目
- 初识java真面目
- 看清卡卡西的真面目
- 看清javascript的真面目!!!
- 男人风韵的真面目
- 认清函数的真面目
- Redis过期机制介绍
- Android MediaCodec 硬编码器封装
- Android博客佳文推荐
- 仿知乎程序(三)读取webService,解析json,volley以及PullToRefreshListView的使用
- 解析xml简单实例,后续继续补充.......
- 不识function真面目【2】
- Redis持久化
- ubuntu12.04 编译litb找不到zlib解决方法
- superGridControl控件中显示图片功能实现
- ZooKeeper典型应用场景一览
- 深度剖析channel
- shell 脚本完成对日志文件的提取之grep 学习
- 开源.net
- goto 的使用注意点