call方法和apply方法的作用及意义是什么?什么时候使用?

mjl 114个月前 提问 源自: JavaScript进阶|函数
0

call方法和apply方法的作用及意义是什么?什么时候使用?

  • 0
    lijsh 114个月前 回答

    `call()`和`apply()`都是JavaScript 中函数对象上的方法:

    ```

    var f = function () {};

    'call' in f; // true

    'apply' in f; // true

    ```

    说到函数,JavaScript 中有个`this`的概念与函数调用相关,`this`指向一个对象,表示函数调用时的执行上下文;当在函数内引用`this`的时候,就会指向这个对象。

    ```

    var man = {

        name: 'Jason',

        sayName: function() { 

            console.log(this.name); 

       }

    }

    man.sayName(); // 输出'Jason' 

    ```

    上面的例子中,`sayName()`是对象`man`上的方法,`sayName()`里`this`指向`sayName()`所在的对象(即`man`),`this.name`实际上是`man.name`,因此最后输出'Jason'。

    如果函数不是对象上的方法,那`this`默认情况下会指向全局上下文,在浏览器中,也就是`window`:

    ```

    window.name = 'Tommy'

    function foo() {

        console.log(this.name);

    }

    foo(); // `this`指向`window`,所以输出'Tommy'

    ```

    明白了`this`之后,`call()`和`apply()`就好解释了。这两个方法的作用是在函数调用时改变函数的执行上下文,也就是函数内的`this`;这两个方法第一个参数,就是希望得到的`this`。

    比如上面的`foo`函数,由于定义在全局环境中,`this`默认指向`window`;如果想更改里面指向的`this`,例如改成`man`,可以调用`foo`的`call()`方法,然后把`man`传进来:

    ```

    foo.call(man); // 输出`man`

    foo.apply(man); // 也是输出`man`

    ```

    两个方法都可以更改函数执行时绑定的`this`;那它们有什么不同呢?主要是在传参上。

    假如`foo`定义时包括了形参:

    ```

    window.name = 'Tommy'

    function foo(a, b) {

        console.log(a + b + this.name);

    }

    ```

    也就是说`foo`调用时期望传进两个参数,所以对于`foo.call()`和`foo.apply()`的形式,第一个参数指定绑定的`this`,后面的参数指定`foo`调用时期望传入的参数(有2个);对于`call`来说,两个参数一个一个传进来;而对于`apply`来说,两个参数必须组成一个数组,以数组方式传进来:

    ```

    foo.call(man, 'Hello, ', 'Mr.'); // 输出‘Hello, Mr.Jason

    foo.apply(man, ['Hello, ', 'Mr.']); // 同样输出‘Hello, Mr.Jason

    ```

    比较下直接调用`foo`的结果

    ```

    foo('Hello, ', 'Mr.'); 输出Hello, Mr.Tommy

    ```







    最佳答案
  • 0
    ciga 114个月前 回答

    1. 作用:设置函数体内的this对象,然后调用函数

    call和apply都用于函数调用,和使用函数名直接调用不同,call和apply可以指定一个额外的参数作为函数体内的this对象。

    看下面示例:

    function greet(){
        console.log("hello " + this.name);
    }
    //三种函数调用方法的比较
    greet(); // 输出: hello
    greet.call({name:"John"}); //输出:hello John
    greet.apply({name:"Mary"}); //输出:hello Mary

    2.区别:参数列表的传入参数方式不同

    call采用不定长的参数列表,而apply使用一个参数数组。

    看下面示例:

    function sub(a,b){
        console.log(a-b);
    }
    sub(10,3);  //输出:7
    sub,call(null,10,3); //输出:7
    sub.apply(null,[10,3]);//输出:7

    3.用途:挪用其他对象的方法

    由于call和apply可以改变函数体内的this指向,因此通常被用来将一个对象原型上的方法应用到另一个对象上。一个常见的应用是

    处理函数的arguments,将其转换为Array类型:

    function test(){   
        var args = Array.prototype.slice.call(arguments,0); //将arguments转化为数组
        console.log(args.join("|")); //输出各参数拼接结果,以|隔开
    }
    test(10,23,190); // 输出:10|23|190




  • 0
    1637654995@qq.com 114个月前 回答
    只是函数调用的一种方法而已