函数的参数arguments
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 :返回一个对函数的引用,该函数调用了当前函数。这个才是调用者
当前上下文this、call apply
方法(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
参考:
http://abruzzi.iteye.com/博客中的“javascript内核系列”
分享到:
相关推荐
`call`和`apply`是`Function.prototype`上的两个方法,它们允许开发者以不同的上下文(`this`值)调用函数,并提供参数。这两个方法的主要区别在于参数的传递方式: 1. **`call`方法**:接收一个`this`值作为第一个...
JavaScript中的call、apply和bind方法都是用来改变函数调用时的上下文(即this值)以及传递参数。它们之间的相同点在于,都能够指定函数执行时的this对象,并且都能接收参数。不同点在于它们的调用方式和执行时机。 ...
_bind、call、apply 是 JavaScript 中的三个函数方法,用于改变函数的执行上下文,即改变函数中的 this 指向。下面我们将详细讲解这三个方法的使用和区别。 作用 _bind、call、apply 三者都是改变函数执行时的上...
在提供的继承示例中,`baseA.call(this)`和`baseB.apply(this, arguments)`分别将`baseA`和`baseB`的构造函数调用上下文设为`this`,从而实现了继承。 此外,`call`和`apply`还可以用于处理数组或类数组对象。比如...
总的来说,`arguments.callee`提供了对当前执行函数的引用,而`call`和`apply`则是用来控制函数执行时的`this`值和参数。在编写JavaScript代码时,了解这些特性可以帮助你更好地理解和利用函数的作用域和上下文。
`call`和`apply`方法则是改变函数调用的上下文(即`this`值)以及传递参数的方式。它们都允许我们指定一个对象作为函数执行时的上下文,并可以控制参数的传递方式。 `call`方法接收两个参数:第一个参数是`this`值...
`call`方法允许我们改变函数调用的上下文(即`this`值),并直接传入参数: ```javascript function sayHello(name) { console.log('Hello, ' + name); } var obj = {name: 'World'}; sayHello.call(obj); // ...
在这个例子中,`callSum` 函数通过`call` 方法调用`sum`函数,`sum`函数内的`this`指向了`callSum`函数的上下文。 apply() 方法的语法如下: ```javascript function.apply(thisObj[, argArray]) ``` 与 call() ...
`apply()`是JavaScript中函数对象的一个方法,它允许我们调用一个函数,并可以自定义函数执行时的上下文(`this`值)以及传入参数。这个方法对于理解和操作JavaScript中的函数和对象关系至关重要。 在JavaScript中...
在JavaScript中,`this`关键字通常表示函数执行时的上下文,即函数被调用的位置。`apply()`方法正是用来改变这个上下文的关键。 1. `apply()`方法的基本使用 `apply()`方法有两个参数:一是要作为函数内部`this`值...
call和apply的主要用途是借用其他对象的方法和改变函数的this上下文。在面向对象编程中,这经常被用来实现继承模式、共享方法等。 call方法的语法是:function.call(thisArg, arg1, arg2, ...),其中thisArg是函数...
总结,`call`和`apply`提供了改变函数执行上下文的能力,而`arguments`对象则允许我们方便地访问函数调用时的所有参数,这些都是JavaScript灵活性和动态性的体现。在实际开发中,掌握这些知识点对于编写高效和灵活的...
arguments对象帮助我们访问函数参数,而this对象则决定了函数执行时的上下文环境。了解并熟练运用这两个属性,能够帮助我们写出更加灵活和强大的JavaScript代码。同时,正确处理this的指向问题,尤其是当涉及到异步...
在JavaScript中,`call`和`apply`是两种非常重要的函数调用方式,它们都用于改变函数执行时的上下文,即改变`this`的指向。这两个方法的主要区别在于它们处理参数的方式。 `call`方法允许你指定一个对象来替代原...
在JavaScript中,`call` 和 `apply` 是两种非常重要的函数调用方式,它们都用于改变函数执行时的上下文(即 `this` 指向),并允许你在不同的对象上使用同一个函数,实现了对象间的继承。下面我们将深入探讨这两个...
在JavaScript中,call与apply是两个非常重要的关键字,它们的功能是改变函数执行时的上下文,也就是函数体内的this指向。通过call和apply可以调用某个函数,并且显式地指定该函数内部的this变量的值。 ### call和...
`each`方法使用`call`或`apply`来改变`iterator`函数的执行上下文,并将当前元素、索引以及集合本身作为参数传递。 `copyMethod`函数用于将`util`对象上的方法复制到`Collection`构造函数的原型上。这里的关键在于`...
在上面的`Student`构造函数中,`Person.apply(this, arguments)`使得`Person`函数的上下文(`this`)变成了`Student`实例,`arguments`对象被用来传递`Person`构造函数所需的参数。因此,尽管`Student`没有直接给`...
JavaScript中的`call`和`apply`是两种非常重要的函数调用方式,它们的主要作用是改变函数执行时的上下文(即`this`的指向),从而解决特定的问题并提供灵活的编程模式。理解这两个方法对于深入JavaScript编程至关...