(十六)call、apply、bind介绍、区别和实现

这篇具有很好参考价值的文章主要介绍了(十六)call、apply、bind介绍、区别和实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

函数中的this指向:

函数中的this指向是在函数被调用的时候确定的,也就是执行上下文被创建时确定的。在一个执行上下文中,this由调用者提供,由调用函数的方式来决定。

类数组对象arguments:

arguments只在函数(除了箭头函数)中存在的类数组参数对象,储存了我们传入的所有参数。

一、call

  • call(this, 参1, 参2, ...),第一个参数为this,后面是函数的一系列参数
  • 当第一个this参数为null、undefind时,默认this指向window
  • 函数立即调用
  • 原理:实际就是把函数放到call传入的第一个参数上,然后再调用该函数。
  • 实现:
/**
 * 手写call
 * @param {*} context
 * @param  {...any} args
 * @returns
 */
Function.prototype.mycall = function (context, ...args) {
  if (typeof this !== "function") {
    throw new TypeError("Error");
  }
  //context不传,默认window
  let _this = context || window;

  //假如原来的context上存在fn属性会产生冲突,暂存一下。
  let temp = null;
  if (_this.fn) {
    temp = _this.fn;
  }

  _this.fn = this;
  // 调用函数
  let res = _this.fn(...args);

  if (temp) {
    //恢复_this对象上的原来的fn属性
    _this.fn = temp;
  } else {
    //删除_this对象上的fn属性
    delete _this.fn;
  }

  return res;

// 测试
let num = 1;
let obj = {
  num: 2,
  fn: "this is obj.fn",
};
function test(a, b, c, d) {
  let num = 1;
  console.log(this.num, "test参数", a, b, c, d);
}
test(4, 3, 2, 1);
// 调用myCall函数
test.mycall(obj, 4, 3, 2, 1);

// 检查obj本身的fn是否被修改
console.log(obj.fn);
};

(十六)call、apply、bind介绍、区别和实现,面试题,javascript,开发语言,ecmascript

注意:这个 undefind,是由于我使用 let 声明的变量。var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性。let 命令、const 命令、class 命令声明的全局变量,不属于顶层对象的属性,而是在一般声明环境 declsEnv 中。

从ES6开始,全局变量和顶层对象的属性开始分离,这意味着使用let和const声明的全局变量不再属于顶层对象的属性,如window对象。这是为了提供更好的模块化和封装,避免全局命名空间的污染。

二、apply

  • applyl(this, arr),第一个参数为this,第二个参数是一个参数数组
  • 当第一个this参数为null、undefind时,默认this指向window
  • 函数立即调用
  • 原理:和call类似,区别就是参数不同,call方法接受的参数是一个参数列表,而apply接受的是一个包含多个参数的数组。
  • 实现:
// 和myCall的不同之处1:参数
Function.prototype.myApply=function(context){
  	if(typeof this!== 'function'){
        throw new TypeError('type error')
    }
  	console.log("myApply", arguments, context, this);
  	let _this = context || window;

  	let temp = null;
  	if (_this.fn) {
    	temp = _this.fn;
  	}
  	_this.fn = this;
  	let res;
  	//   判断是否存在第二个参数
  	if (arguments[1]) {
    	res = _this.fn(...arguments[1]);
  	} else {
    	res = _this.fn();
  	}
 // 删除context对象上的fn属性
  	if (temp) {
    	_this.fn = temp;
  	} else {
    	delete _this.fn;
  	}
 	 return res;
}

// 测试
let num = 1;
let obj = {
  num: 2,
  fn: "this is obj.fn",
};
function test(a, b, c, d) {
  let num = 1;
  console.log(this.num, "test参数", a, b, c, d);
}
test(4, 3, 2, 1);
// 调用myCall函数
test.myApply(obj, [4, 3, 2, 1]);

// 检查obj本身的fn是否被修改
console.log(obj.fn);

结果:
(十六)call、apply、bind介绍、区别和实现,面试题,javascript,开发语言,ecmascript

三、bind

  • bind(this, 参1, 参2, ...),第一个参数为this,后面是函数的一系列参数
  • 当第一个this参数为null、undefind时,默认this指向window
  • bind方法的返回值是函数,不会立即调用
  • 原理:(1)bind返回的函数作为构造函数使用的时候,bind绑定的this会失效,到那时参数有效。(2)如何判断bind 是正常使用还是当构造函数,根据this。当为构造函数时,this指向实例对象(this的prototype在该构造函数上)
  • 实现:
Function.prototype.myBind = function (_this) {
  if (typeof this !== "function") {
    throw new TypeError("_this must be a function");
  }
  //获取参数
  let args0 = [...arguments].slice(1);
  //保存this,如果作为构造函数使用,此时this会指向实例
  let that = this;
  let context = _this||window;
  return function Fn(...args) {
    // 如果是new的形式来使用绑定函数的
    if (this instanceof Fn) {
      return new that(...args0, ...args);
    } else {
      return that.call(context , ...args0, ...args);
    }
  };
};

//测试:
function Point(x, y) {
  this.x = x;
  this.y = y;
}

// 情况1:正常调用bind函数
let testObj = {};
let MyPoint = Point.myBind(testObj, 0);
MyPoint(1);
console.log(testObj);
//情况2:bind返回的函数作为构造函数
let newObj = new MyPoint(2);
console.log(newObj);

结果:
(十六)call、apply、bind介绍、区别和实现,面试题,javascript,开发语言,ecmascript

四、区别:

1、相同点:
(1) call、apply、bind 都有改变this指向的作用。
(2)都可以给参数传参
2、不同点:
(1)call、bind 的第二个、后续参数是多个;而apply接收的第二参数是数组。
(2)call、apply会立即执行参数;而bind不会立即执行,得再调用才能执行。

参考:
1、https://blog.csdn.net/weixin_51472145/article/details/132566180
2、https://blog.csdn.net/weixin_40856652/article/details/124293144?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171348813116800178533534%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=171348813116800178533534&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-124293144-null-null.142v100pc_search_result_base1&utm_term=call%E3%80%81apply%E5%92%8Cbind%E7%9A%84%E5%8C%BA%E5%88%AB&spm=1018.2226.3001.4187
3、https://blog.csdn.net/sinat_41904410/article/details/104396112文章来源地址https://www.toymoban.com/news/detail-855918.html

到了这里,关于(十六)call、apply、bind介绍、区别和实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端 JS 经典:apply、call、bind

    1. 概念 都是用来改变函数中 this 指向的。区别在于 apply、call 传参方式不一样,调用后,直接执行函数。bind 调用后,返回一个函数体,不直接执行函数。 2. 为什么用 那为什么要改变 this 指向呢。正常情况下,谁调用函数 this 就指向谁。那调用这个函数的那个谁,要访问另一

    2024年02月07日
    浏览(32)
  • 【JavaScript】手撕前端面试题:手写Object.create | 手写Function.call | 手写Function.bind

    🖥️ NodeJS专栏:Node.js从入门到精通 🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述) 🖥️ TypeScript知识总结:TypeScript从入门到精通(十万字超详细知识点总结) 🧑‍💼个人简介:大三学生,一个不甘平庸的平凡人🍬 👉

    2024年02月21日
    浏览(44)
  • Js:apply/call/bind、作用域/闭包、this指向(普通,箭头,JS/Vue的this)

    共同点: apply()、call() 和 bind() 方法 三者作用都是 改变this指向。 接收的第一个参数都是this要指向的对象 区别: apply只有两个参数,第二个参数为数组; call和bind传参相同,多个参数依次传入的; call和apply都是对函数进行直接调用(立即执行),而bind方法不会立即调用函数

    2023年04月08日
    浏览(82)
  • 17 JavaScript 中的call和apply

    17 JavaScript 中的call和apply 对于咱们逆向工程师而言. 并不需要深入的理解call和apply的本质作用. 只需要知道这玩意执行起来的逻辑顺序是什么即可 在运行时. 正常的js调用: 接下来, 我们可以使用call和apply也完成同样的函数调用 apply和他几乎一模一样. 区别是: apply传递参数要求是

    2024年02月11日
    浏览(30)
  • 54-函数的3种定义,函数的4种调用:函数模式调用,方法模式调用,构造函数模式调用,apply call bind调用

    一.函数的3种定义  1.函数的声明定义:具有声明提升 2.函数的表达式定义 3.构造函数定义 var 变量 = new F unction(\\\"形参1\\\",\\\"形参2\\\",\\\"形参3\\\",\\\"方法体\\\"); 二.函数的4种调用 1普通模式调用 2. 内联模型 函数模式调用, this 指向 window  

    2024年01月25日
    浏览(38)
  • 【JavaScript】Function的祖传方法call与apply

    看了本文您能了解到的知识! 在本篇文章中,将带你了解 什么是call和apply , call和apply的用途 、如何手写 call 和 apply 以及 call 和 apply 的使用场景。 call() 和 apply() 是 JavaScript 中的两个内置方法,用于调用函数并指定函数中的 this 值。 两者的区别是: call() 方法的语法和作用

    2024年02月17日
    浏览(39)
  • js--手写call和apply方法干货注释满满

    我们都知道js中call和apply都是改变this指向的,这篇文章我们一起来实现call和apply的底层吧!我们先来看一下js中的call和apply的用法 一.用法 1.call用法 传递参数逗号分隔 2.apply用法 传递参数为数组 二.手写实现call 1.手写myCall改变this指向 这里this指向已经改变,但是还不可以传递

    2024年02月06日
    浏览(35)
  • 【延伸学习】TS(JS)类的继承(prototype、call、apply,extends)

    PS:文末附上完整的代码(是在CocosCreator下运行的) 一. 基(父)类   基类包含三个成员变量(名字、年龄)还有一个后面用于测试的数组,两个原型方法(输出名字,输出年龄),还有一个类似静态函数的方法。 基类唯一测试的,就是用类名可以直接调用eat这个静态方法。

    2024年01月25日
    浏览(31)
  • 【Java集合类面试二十六】、介绍一下ArrayList的数据结构?

    文章底部有个人公众号: 热爱技术的小郑 。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:介绍一下ArrayList的数据结构? 参考答案: ArrayList的底

    2024年02月08日
    浏览(33)
  • javascript基础二十六:JavaScript中如何实现函数缓存?有哪些应用场景?

    一、是什么 函数缓存,就是将函数运算过的结果进行缓存 本质上就是用空间(缓存存储)换时间(计算过程) 常用于缓存数据计算结果和缓存对象 缓存只是一个临时的数据存储,它保存数据,以便将来对该数据的请求能够更快地得到处理 二、如何实现 实现函数缓存主要依

    2024年02月07日
    浏览(80)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包