JavaScript中call,apply,bind的区别与实现

JavaScript中的call, apply, bind这三个方法都用于改变函数的this指向。下面分开讲解它们的用途、区别以及实现原理。

1. call方法

1.1 用途

call方法可以借用另一个对象的方法,并且将this指向当前对象。

1.2 示例说明

以下是一个简单的示例,调用Array.prototype.push方法将一个数组合并到另一个数组中。

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

Array.prototype.push.call(arr1, ...arr2);

console.log(arr1); // [1, 2, 3, 4, 5, 6]

在这个例子中,我们借用了Array.prototype.push方法,并将它的this指向了arr1对象。

2. apply方法

2.1 用途

apply方法和call方法一样,可以借用另一个对象的方法,但是参数需要以数组的形式传递。

2.2 示例说明

下面的示例展示了如何使用apply方法。

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

Array.prototype.push.apply(arr1, arr2);

console.log(arr1); // [1, 2, 3, 4, 5, 6]

在这个示例中,我们使用了apply方法,它的参数需要以数组的形式传递,并将Array.prototype.push方法的this指向arr1。

3. bind方法

3.1 用途

bind方法用于创建一个新函数,并将它的this指向指定的对象,但是不会立即执行函数。

3.2 示例说明

以下是一个示例,演示了如何使用bind方法。

function Animal(name) {
  this.name = name;
}

Animal.prototype.sayName = function() {
  console.log(this.name);
};

const cat = new Animal('Kitty');

const sayCatName = cat.sayName.bind(cat);

sayCatName(); // 输出 "Kitty"

在这个示例中,我们使用bind方法创建了一个新函数sayCatName,并将它的this指向了cat,调用它时,它的this将会指向cat,输出了"Kitty"。

4. 实现原理

call、apply、bind这三个方法的实现原理都类似,以下是它们的伪代码实现:

Function.prototype.myCall = function(thisArg) {
  // 判断是否是函数调用
  if (typeof this !== 'function') {
    throw new TypeError('not callable');
  }

  // 保证thisArg是一个对象
  thisArg = thisArg || window;

  // 使用Symbol类型创建独一无二的键名
  const key = Symbol();

  // 将当前函数作为thisArg对象的一个方法
  thisArg[key] = this;

  // 执行函数并获取返回值
  const args = [].slice.call(arguments, 1);
  const result = thisArg[key](...args);

  // 删除新增的方法并返回执行结果
  delete thisArg[key];
  return result;
};

Function.prototype.myApply = function(thisArg, args = []) {
  if (typeof this !== 'function') {
    throw new TypeError('not callable');
  }

  thisArg = thisArg || window;

  const key = Symbol();

  thisArg[key] = this;

  const result = thisArg[key](...args);

  delete thisArg[key];
  return result;
};

Function.prototype.myBind = function(thisArg, args = []) {
  if (typeof this !== 'function') {
    throw new TypeError('not callable');
  }

  thisArg = thisArg || window;

  const fn = this;

  return function() {
    const innerArgs = [].slice.call(arguments);
    const argsList = args.concat(innerArgs);
    return fn.apply(thisArg, argsList);
  };
};

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript中call,apply,bind的区别与实现 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • JavaScript中的创建枚举四种方式

    当我们需要为了提高程序的可读性和可维护性的目的,要定义一些有限的可能性的常量时,就需要使用枚举了。在 JavaScript 中,以下是创建枚举的四种方式: 1. 使用对象 通过定义一个对象,我们可以实现基本的枚举功能。 const DAY_OF_WEEK = { SUNDAY: 0, MONDAY: 1, TUESDAY: 2, WEDNESDAY: 3, …

    JavaScript 2023年6月10日
    00
  • JavaScript字符串对象的concat方法实例(用于连接两个或多个字符串)

    JavaScript字符串对象的concat方法可用于连接两个或多个字符串,其语法为: str.concat(string2, string3, …, stringX) 其中,str 是原始字符串,string2、string3 等是要连接的字符串。 示例一:连接两个字符串 const str1 = ‘Hello’; const str2 = ‘worl…

    JavaScript 2023年5月28日
    00
  • html页面展示json数据并格式化的方法

    展示 JSON 数据并格式化,通常有以下两种方法: 方法一:通过 JavaScript 进行格式化 通过 JavaScript 获取到 JSON 数据之后,可以使用 JSON 的 stringify 方法进行格式化,再将格式化后的结果插入到 HTML 页面中即可。 示例代码: <!DOCTYPE html> <html> <he…

    JavaScript 2023年5月27日
    00
  • js设置document.domain实现跨域的注意点分析

    关于“js设置document.domain实现跨域的注意点分析”的攻略,我将详细介绍如下: 什么是跨域? 在 Web 开发中,跨域是指在一个域下的文档或脚本试图去请求另一个域下的资源。简单来说,当浏览器向一个网站的服务器发送请求时,如果该请求要访问另外一个域名下的资源(比如 JavaScript 文件、CSS 文件等),那么就会发生跨域问题。 为什么需要跨…

    JavaScript 2023年6月10日
    00
  • 使用Vue实现移动端左滑删除效果附源码

    针对“使用Vue实现移动端左滑删除效果附源码”,我可以提供以下完整攻略。 前置知识 实现该功能需要具备以下基础知识: Vue.js基本语法 移动端touch事件基本知识 CSS3动画基本知识 实现步骤 第一步:实现左滑效果 首先,我们需要实现左滑效果。我们可以使用CSS3的transition或animation属性实现。 以使用transition为例,我…

    JavaScript 2023年6月11日
    00
  • 理解javascript函数式编程中的闭包(closure)

    理解 javascript 函数式编程中的闭包(closure)可以分为以下几个步骤: 什么是闭包? 闭包是指一个函数访问了自己定义的外部函数的作用域中的变量。简单来说,就是在一个函数内部可以访问另一个函数作用域中的变量。在 JavaScript 中,当一个函数定义在另一个函数内部时,就会形成一个闭包。 闭包的使用 保存私有变量 闭包可以用来定义私有变量。这…

    JavaScript 2023年6月10日
    00
  • JavaScript使用FileSystemObject对象写入文本文件内容的方法

    JavaScript的在浏览器端不能直接访问本地文件系统,但是可以通过ActiveXObject对象创建FileSystemObject对象来访问文件系统,可以使用FileSystemObject对象提供的方法进行文件读写操作。本文将详细讲解如何使用FileSystemObject对象写入文本文件内容的方法。 准备工作 在使用FileSystemObject…

    JavaScript 2023年5月27日
    00
  • 怎么清空javascript数组

    当我们需要清空一个 JavaScript 数组时,有以下几种方法可以实现。 方法一:重新赋值 可以通过重新将一个空数组赋值给目标数组来清空该数组。代码如下: let arr = [1,2,3,4]; arr = []; console.log(arr); // 输出 [] 在上面的代码中,我们将一个包含 1 到 4 的数组赋给变量 arr,然后使用空数组重新…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部