函数的参数arguments、当前上下文this、call apply

[b][color=green]函数的参数arguments[/color][/b]
js中的各式“伪数组”,如arguments、与dom有关的childNodes等,这些对象虽然也有length属性,也可以通过数字下标索引元素,但它们不是Array对象,而是Object对象,通过它们的constructor属性就可以很清晰的判断出来了。
javascript在处理函数的参数时,与其他编译型的语言不一样。在javascript中,解释器传递给函数的是一个类似于数组的内部值,叫arguments,这个在函数对象生成的时候就被初始化了。先通过一个例子来讨论这个神奇的arguments:
function sum(){
var len = arguments.length
for(var i=0; i<len; i++){
alert(arguments[i]); //查看arguments伪数组
}

var result = 0;
for(var i=0; i<len; i++){
var current = arguments[i];
if(isNaN(current)){
throw new Error("not a number exception");
}else{
result += current;
}
}
return result;
}
sum(); //此时sum方法中,arguments为空数组,arguments.length=0
sum(10, 20, 30, 40); //数组arguments.length=4 返回结果100
sum(4, 8, 15, 16, 23, 42);//数组arguments.length=6 108
sum("new");//数组arguments.length=1 报错Error: not a number exception

运行结果可以看出:函数sum并没有定义显式的形参,而我们又可以动态的传递给其任意多的参数,那么,如何在sum函数中如何引用这些参数呢?这里就需要用到arguments这个对象。
再看个例子:
function f(x,y){
alert(x+" === "+y);
var len = arguments.length
for(var i=0; i<len; i++){
alert(arguments[i]); //查看arguments数组
}
}
f(1);
f(1,2);
f(1,2,3);
//运行结果表明:如果声明时函数的参数小于传进来的参数个数,那么在函数体内部可以使用arguments获得其他的参数

//给函数传了一个叫a的参数,并且只有这一个参数,那么a与arguments[0]都是对这个参数值的引用,改变其中一个值,即改变了二者所有的值
function change(a){
alert(a); //比如我传的a为gerry,那么alert就是gerry;如果啥也没传就会alert undefined
arguments[0]='xiaoxiaozi'; //用arguments[0]改变了这个参数的值
alert(a); //没错,这个值变成了xiaoxiaozi
}

//阶乘方法:n*(n-1)*(n-2)*...*3*2*1   
function factorial(n){
if(n == 1){
return 1;
}else{
return n * factorial(n - 1);
}
}
//改为三元实现:
function factorial(n){
return n==0 ? 1 : n * factorial(n-1);
}
//匿名调用:
(function(x){
return x == 0 ? 1 : x * arguments.callee(x-1);
})(10);//3628800
其中,arguments.callee表示函数本身,也就是被调用者。caller是调用者
callee :返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文。
caller :返回一个对函数的引用,该函数调用了当前函数。这个才是调用者


[b][color=green]当前上下文this、call apply[/color][/b]
方法(Method)本身就是是函数(function),只不过方法的使用更受限制。
我们知道,每一个对象都包含0个或多个属性,属性可以是任意类型,当然也包括对象。函数本身就是一种对象,因此我们完全可以把一个函数放到一个对象里面,此时,这个函数就成了对象的一个方法。此后如果要使用该方法,则可以通过对象名利用"."操作符来实现。
方法的调用需要对象的支持,那么在方法中如何获取对象呢?this!this关键字表示调用该方法的对象,也就是说通过对象调用方法的时候,this关键字会指向该对象。例如:
domObj.onclik = function(){
clickFun(this);//onclick是对象domObj的方法,故这里的this就是domObj
}
在javascript中,this表示当前上下文,即调用者的引用(this表示对方法调用者(对象)的引用)。this的值并非函数如何被声明而确定,而是被函数如何被调用而确定,这一点与传统的面向对象语言截然不同。函数的上下文是可以变化的,因此,函数内的this也是可以变化的,函数可以作为一个对象的方法,也可以同时作为另一个对象的方法,总之,this只是在任意对象和function元素结合时的一个概念,函数本身是独立的。可以通过Function对象上的call或者apply函数来修改函数的上下文。
call和apply是Function上的函数,通常用来修改函数的上下文,函数中的this指针将被替换为call或者apply的第一个参数,例如:
var name = "the name of window";//定义一个全局变量,name
var jack = { //定义一个人,名字为jack
name : "jack",
age : 26
}
var gerry = { //定义另一个人,名字为gerry
name : "gerry",
age : 25
}
function printName(){ //定义一个全局的函数对象
return this.name;
}

//设置printName的上下文为jack, 此时的this为jack
alert(printName.call(jack));
//设置printName的上下文为gerry,此时的this为gerry
alert(printName.call(gerry));
//设置printName的上下文为window,此时的this为window,打印"the name of window"
alert(printName.call(window));
//直接调用函数,此时即:调用window对象的printName方法。调用window对象的属性或者方法时,可以省略window对象,直接调用。也打印"the name of window"
printName();

//改为apply实现:
alert(printName.apply(jack));
alert(printName.apply(gerry));

只有一个参数的时候call和apply的使用方式是一样的,如果有多个参数时,apply的第二个参数为函数需要的参数组成的一个数组,而call则直接跟若干个参数,参数之间以逗号(,)隔开:
setName.apply(jack, ["tom"]);
alert(printName.apply(jack)); //打印tom

setName.call(gerry, "gerry wang");
alert(printName.call(gerry)); //打印gerry wang


参考:[url]http://abruzzi.iteye.com/[/url]博客中的“javascript内核系列”
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值