js中的call和apply

xiaoxiao2021-02-28  116

使用 .call(), .apply() 和 .bind() 改变上下文

.call() 和 .apply()函数用于在调用函数时改变上下文。这给了你令人难以置信的编程能力(和一些终极权限来驾驭代码)。 要使用call或apply函数,您只需要在函数上调用它,而不是使用一对括号调用函数,并将新的上下文作为第一个参数传递。 函数自己的参数可以在上下文之后传递。(愚人码头注:call或apply用另一个对象来调用一个方法,将一个函数上下文从初始的上下文改变为指定的新对象。简单的说就是改变函数执行的上下文。)

JavaScript 代码:

function hello() {

   // do something...

}

 

hello(); // 通常的调用方式

hello.call(context); // 在这里你可以传递上下文(this 值)作为第一个参数

hello.apply(context); // 在这里你可以传递上下文(this 值)作为第一个参数

.call()和.apply()之间的区别在于,在.call()中,其余参数作为以逗号分隔的列表,而.apply()则允许您在数组中传递参数。

JavaScript 代码:

function introduce(name, interest) {

   console.log('Hi! I\'m '+ name +' and I like '+ interest +'.');

   console.log('The value of this is '+ this +'.')

}

 

introduce('Hammad', 'Coding');  // 通常的调用方式

introduce.call(window, 'Batman', 'to save Gotham'); // 在上下文之后逐个传递参数

introduce.apply('Hi', ['Bruce Wayne', 'businesses']); // 在上下文之后传递数组中的参数

 

// 输出:

// Hi! I'm Hammad and I like Coding.

// The value of this is [object Window].

// Hi! I'm Batman and I like to save Gotham.

// The value of this is [object Window].

// Hi! I'm Bruce Wayne and I like businesses.

// The value of this is Hi.

.call()的性能要比.apply()稍快。

以下示例将文档中的项目列表逐个记录到控制台。

HTML 代码:

<!DOCTYPE html>

<html lang="en">

<head>

   <meta charset="UTF-8">

   <title>Things to learn</title>

</head>

<body>

   <h1>Things to Learn to Rule the World</h1>

   <ul>

       <li>Learn PHP</li>

       <li>Learn Laravel</li>

       <li>Learn JavaScript</li>

       <li>Learn VueJS</li>

       <li>Learn CLI</li>

       <li>Learn Git</li>

       <li>Learn Astral Projection</li>

   </ul>

   <script>

       // 在listItems中保存页面上所有列表项的NodeList

       var listItems = document.querySelectorAll('ul li');

       // 循环遍历listItems NodeList中的每个节点,并记录其内容

       for (var i = 0; i < listItems.length; i++) {

         (function () {

           console.log(this.innerHTML);

         }).call(listItems[i]);

       }

 

       // Output logs:

       // Learn PHP

       // Learn Laravel

       // Learn JavaScript

       // Learn VueJS

       // Learn CLI

       // Learn Git

       // Learn Astral Projection

   </script>

</body>

</html>

HTML仅包含无序的项目列表。然后 JavaScript 从DOM中选择所有这些项目。列表循环,直到列表中的项目结束。在循环中,我们将列表项的内容记录到控制台。

该日志语句包裹在一个函数中,该 call 函数包含在调用函数中的括号中。将相应的列表项传递给调用函数,以便控制台语句中的 this 关键字记录正确对象的 innerHTML 。

对象可以有方法,同样的函数对象也可以有方法。 事实上,JavaScript函数附带了四种内置方法:

Function.prototype.apply()

Function.prototype.bind() ( ECMAScript 5 (ES5) 中引进)

Function.prototype.call()

Function.prototype.toString()

Function.prototype.toString() 返回函数源代码的字符串表示形式。

与 .call() 和 .apply()不同,.bind() 本身不调用该函数,它只能用于在调用函数之前绑定上下文和其他参数的值。在上面的一个例子中使用 .bind() :

JavaScript 代码:

(function introduce(name, interest) {

   console.log('Hi! I\'m '+ name +' and I like '+ interest +'.');

   console.log('The value of this is '+ this +'.')

}).bind(window, 'Hammad', 'Cosmology')();

 

// logs:

// Hi! I'm Hammad and I like Cosmology.

// The value of this is [object Window].

.bind() 就像.call()函数一样,它允许你传递其余的参数,用逗号分隔,而不是像apply,在数组中传递参数。

转载请注明原文地址: https://www.6miu.com/read-52756.html

最新回复(0)