`

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

 
阅读更多
函数的参数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内核系列”
分享到:
评论

相关推荐

    理解JavaScript的caller callee call apply

    `call`和`apply`是`Function.prototype`上的两个方法,它们允许开发者以不同的上下文(`this`值)调用函数,并提供参数。这两个方法的主要区别在于参数的传递方式: 1. **`call`方法**:接收一个`this`值作为第一个...

    【JavaScript源代码】JavaScript函数之call、apply以及bind方法案例详解.docx

    JavaScript中的call、apply和bind方法都是用来改变函数调用时的上下文(即this值)以及传递参数。它们之间的相同点在于,都能够指定函数执行时的this对象,并且都能接收参数。不同点在于它们的调用方式和执行时机。 ...

    前端大厂最新面试题-bind_call_apply.docx

    _bind、call、apply 是 JavaScript 中的三个函数方法,用于改变函数的执行上下文,即改变函数中的 this 指向。下面我们将详细讲解这三个方法的使用和区别。 作用 _bind、call、apply 三者都是改变函数执行时的上...

    js中call与apply的用法小结.docx

    在提供的继承示例中,`baseA.call(this)`和`baseB.apply(this, arguments)`分别将`baseA`和`baseB`的构造函数调用上下文设为`this`,从而实现了继承。 此外,`call`和`apply`还可以用于处理数组或类数组对象。比如...

    详解JavaScript函数callee、call、apply的区别

    总的来说,`arguments.callee`提供了对当前执行函数的引用,而`call`和`apply`则是用来控制函数执行时的`this`值和参数。在编写JavaScript代码时,了解这些特性可以帮助你更好地理解和利用函数的作用域和上下文。

    Javascript - 全面理解 caller,callee,call,apply

    `call`和`apply`方法则是改变函数调用的上下文(即`this`值)以及传递参数的方式。它们都允许我们指定一个对象作为函数执行时的上下文,并可以控制参数的传递方式。 `call`方法接收两个参数:第一个参数是`this`值...

    Javascript - 全面理解 caller,callee,call,apply (转载)

    `call`方法允许我们改变函数调用的上下文(即`this`值),并直接传入参数: ```javascript function sayHello(name) { console.log('Hello, ' + name); } var obj = {name: 'World'}; sayHello.call(obj); // ...

    跟我学习javascript的call(),apply(),bind()与回调

    在这个例子中,`callSum` 函数通过`call` 方法调用`sum`函数,`sum`函数内的`this`指向了`callSum`函数的上下文。 apply() 方法的语法如下: ```javascript function.apply(thisObj[, argArray]) ``` 与 call() ...

    apply应用小结

    `apply()`是JavaScript中函数对象的一个方法,它允许我们调用一个函数,并可以自定义函数执行时的上下文(`this`值)以及传入参数。这个方法对于理解和操作JavaScript中的函数和对象关系至关重要。 在JavaScript中...

    JS中用法apply方法通过不同数量的参数调用函数的方法_.docx

    在JavaScript中,`this`关键字通常表示函数执行时的上下文,即函数被调用的位置。`apply()`方法正是用来改变这个上下文的关键。 1. `apply()`方法的基本使用 `apply()`方法有两个参数:一是要作为函数内部`this`值...

    javascript下arguments,caller,callee,call,apply示例及理解

    call和apply的主要用途是借用其他对象的方法和改变函数的this上下文。在面向对象编程中,这经常被用来实现继承模式、共享方法等。 call方法的语法是:function.call(thisArg, arg1, arg2, ...),其中thisArg是函数...

    JS中call/apply、arguments、undefined/null方法详解

    总结,`call`和`apply`提供了改变函数执行上下文的能力,而`arguments`对象则允许我们方便地访问函数调用时的所有参数,这些都是JavaScript灵活性和动态性的体现。在实际开发中,掌握这些知识点对于编写高效和灵活的...

    JS函数内部属性之arguments和this实例解析

    arguments对象帮助我们访问函数参数,而this对象则决定了函数执行时的上下文环境。了解并熟练运用这两个属性,能够帮助我们写出更加灵活和强大的JavaScript代码。同时,正确处理this的指向问题,尤其是当涉及到异步...

    详解js中的apply与call的用法.docx

    在JavaScript中,`call`和`apply`是两种非常重要的函数调用方式,它们都用于改变函数执行时的上下文,即改变`this`的指向。这两个方法的主要区别在于它们处理参数的方式。 `call`方法允许你指定一个对象来替代原...

    JS中call和apply函数用法实例分析

    在JavaScript中,`call` 和 `apply` 是两种非常重要的函数调用方式,它们都用于改变函数执行时的上下文(即 `this` 指向),并允许你在不同的对象上使用同一个函数,实现了对象间的继承。下面我们将深入探讨这两个...

    详解js中call与apply关键字的作用

    在JavaScript中,call与apply是两个非常重要的关键字,它们的功能是改变函数执行时的上下文,也就是函数体内的this指向。通过call和apply可以调用某个函数,并且显式地指定该函数内部的this变量的值。 ### call和...

    javascript利用apply和arguments复用方法

    `each`方法使用`call`或`apply`来改变`iterator`函数的执行上下文,并将当前元素、索引以及集合本身作为参数传递。 `copyMethod`函数用于将`util`对象上的方法复制到`Collection`构造函数的原型上。这里的关键在于`...

    全面了解构造函数继承关键apply call

    在上面的`Student`构造函数中,`Person.apply(this, arguments)`使得`Person`函数的上下文(`this`)变成了`Student`实例,`arguments`对象被用来传递`Person`构造函数所需的参数。因此,尽管`Student`没有直接给`...

    javascript中call apply 的应用场景

    JavaScript中的`call`和`apply`是两种非常重要的函数调用方式,它们的主要作用是改变函数执行时的上下文(即`this`的指向),从而解决特定的问题并提供灵活的编程模式。理解这两个方法对于深入JavaScript编程至关...

Global site tag (gtag.js) - Google Analytics