手写apply、call、bind(大量代码)

随笔 专栏收录该内容
18 篇文章 1 订阅

最近又进行了基础知识的重新学习,然后进行了call,apply,bind的this指向参数类型以及代码的手写,然后整理了下。

this指向

// this指向
const phper = {
    name: 'php',
    getName: function(){
        console.log(this.name+'is the best language in the world');
 } }; const webfansDoLi = {  name: 'javascript', }; phper.getName(); phper.getName.call(webfansDoLi); phper.getName.apply(webfansDoLi) phper.getName.bind(webfansDoLi)()  //打印结果:javascript is the best language in the world //打印结果:javascript is the best language in the world //打印结果:javascript is the best language in the world  

结论:call、apply、bind的this都是指向他们的第一个参数

参数类型

// 参数注入(异同比较)
const developer = {
    getSkills: function(...args){
        console.log(...args);
    },
}; const webfansDoLi = {  getSkills: ['html'], } developer.getSkills.call(webfansDoLi,'es6','计算机基础'); developer.getSkills.apply(webfansDoLi,['hBuilder','微信小程序']); developer.getSkills.bind(webfansDoLi,'vue','react')() //打印结果:es6 计算机基础 //打印结果:hBuilder 微信小程序 //打印结果:vue react 

结论:call和bind的第二个参数是开始都是实参参与,而apply则是第二个参数是参数数组(速记参数差异:apply参数是array,都是a开头)。

手写绑定

所有的绑定都是绑定在Function函数的prototype属性上的。

手写call

// 简易模拟实现--call
Function.prototype.apply = function(context){
   console.log(1)
   //重定义this
   const DoLi = context || window;
 //模拟档期那的对象的this指向  DoLi.func = this;  //获取参数  const args = Array.from(arguments).slice(1);  //绑定参数  const res = arguments.length>1?DoLi.func(...args):DoLi.func();  //清除定义的this  delete DoLi.func;  //返回结果  return res; } let a = {  name: 'I am a',  sayName: function(out){  console.log(this.name+(out?out:""));  } }; let b = {  name: 'I am b' }; a.sayName.apply(b,['我是额外参数','参数2'])  //输出结果:1 //输出结果:I am b我是额外参数,参数2 

难点:this指向和参数列表截取需要注意

手写apply

// 简易模拟实现--apply
Function.prototype.apply = function(context){
    console.log(1)
    //重定义this
    const DoLi = context || window;
 //模拟档期那的对象的this指向  DoLi.func = this;  //获取参数  const args = Array.from(arguments).slice(1,);  //绑定参数  const res = arguments.length>1?DoLi.func(args):DoLi.func();  //清除定义的this  delete DoLi.func;  //返回结果  return res; } let a = {  name: 'I am a',  sayName: function(out){  console.log(this.name+(out?out:""));  } }; let b = {  name: 'I am b' }; a.sayName.apply(b,['我是额外参数','参数2'])  //输出结果:1 //输出结果:I am b我是额外参数,参数2  

难点:能写出上面的call的话,这个只需要注意下第二个参数是数组就可以

手写bind

// 简易模拟实现--bind
Function.prototype.bind = function(context){
    console.log(1)
    //深拷贝,防止污染
    const DoLi = JSON.parse(JSON.stringify(context)) || window;
 //模拟档期那的对象的this指向  DoLi.func = this;  //获取参数  const args = Array.from(arguments).slice(1,);  // 返回一个绑定的函数,等待调用  return function() {  //返回结果  return args.length>0?DoLi.func(...args):DoLi.func();  } } let a = {  name: 'I am a',  sayName: function(out){  console.log(this.name+(out?out:""));  } }; let b = {  name: 'I am b' }; a.sayName.bind(b,['我是额外参数','参数2'])()  //输出结果:1 //输出结果:I am b我是额外参数,参数2 

难点:手写bind函数需要返回一个绑定函数,而不是一个结果。

好的,完成。

月如钩,无言独上西楼 ——煜李

本文使用 mdnice 排版

  • 0
    点赞
  • 2
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值