一直以来,对call函数都不是很理解,经常看到用,有时候把,觉得挺好理解的,有时候吧,又觉得摸不清头脑,最近在看d3,里面又遇到call,所以,还是得把这个问题理解透彻。现在把我的理解记录如下:
call函数的作用,最常用的概况,就是改变this的指向,确实是,可是怎么理解呢?先来看下一个简单是实现原理

Function.prototype.$call = function(context,...args){const fn = this;//先将this即这个调用call的函数赋值给一个常量fn
context.fn = fn;//给传入的对象新增属性,并将其指向前面的调用call的函数
context.fn(...args);//传入的对象调用执行(调用call的函数),后面为传入的参数
delete context.fn//删除传入context对象下的fn属性
}
function test(){console.log('总和是':this.a+this.b)
}
const obj = {a:1,b:2};
test.$call(window)//window调用,打印'总和是NaN'
test.$call(obj)//obj调用,打印'总和是3'

通过$call方法模拟call,是如何将函数中的this属性改变的,就是给传入的对象增加属性,调用(调用call的方法)来改变this,具体实现

//1.先写立即执行函数
;(function(){function calls(context){//如果后面要带参数进去,这个context要必传,如果无关紧要,可用为null//3.判断是否传参,如果有,包装为对象,否则,就是windowcontext = context?Object(context):window;//4.将this指向为context.fn的属性context.fn = this;//5.可能后面会有多个参数,这个就是call和apply的区别,call是一个一个传,而apply则传入的是一个数组const args = [];for(let i = 1;i<arguments.length;i++){//i从1开始,因为第一个为对象args.push(arguments[i])}//6.调用context.fn函数const res = context.fn(...args);//7.删除对象上的fn属性delete context.fn//8.最后返回return res;}//2.将calls挂载到函数的原型对象上面Function.prototype.calls = calls;
})()
//将上面函数调用过来,结果一样
function test(){console.log('总和是':this.a+this.b)
}
const obj = {a:1,b:2};
test.$call(window)//window调用,打印'总和是NaN'
test.$call(obj)//obj调用,打印'总和是3'

由于箭头函数的this,是在哪里申明就是那里,因此,call,apply的方法对箭头函数涉及到this则无用,如果只是传参借用还是可用,call和apply的区别则只是传参的区别,在calls中注释中有提及。

js中call函数理解相关推荐

  1. java js中 function函数报错_浅析JS中对函数function的理解(基础篇)

    正文:我们知道,在js中,函数实际上是一个对象,每个函数都是Function类型的实例,并且都与其他引用类型一样具有属性和方法.因此,函数名实际上是指向函数对象的指针,不与某个函数绑定.在常见的两种定 ...

  2. Js中匿名函数的理解

    目录 1.js中匿名函数的N种写法 最常见的用法: 2.JavaScript 匿名函数及闭包 2.1 匿名函数 2.1.1 函数的定义 2.1.2 匿名函数的创建 2.2 闭包 2.3 举例 2.4 ...

  3. JS OOP -02 深入认识JS中的函数

    深入认识JS中的函数: 1.概述,认识函数对象 2.函数对象和其他内部对象的关系 3.将函数作为参数传递 4.传递给函数的隐含参数:arguments 5.函数的apply,call方法和length ...

  4. 谈谈JS中的函数劫持

    说到劫持,第一反应可能是什么不好的东西.函数劫持并不邪恶,关键是看使用的人.虽然这个概念在前端领域使用较少,但是在安全领域.自定义业务等场景下还是有一定的使用价值的.所以,这一篇文章将会和大家一起去了 ...

  5. JS中setter/getter理解

    JS中setter/getter理解 JS对象属性 get/set和getter/setter 数据属性 Object.defineProperty() 访问器属性 getter/setter创建及删 ...

  6. JS中Promise函数then的奥秘探究

    JS中Promise函数then的奥秘探究 Promise概述 Promise对象是CommonJS工作组提出的一种规范,目的是为异步操作提供统一接口. 那么,什么是Promises? 首先,它是一个 ...

  7. JS中的函数,Array对象,for-in语句,with语句,自定义对象,Prototype

    一)函数 A)JS中的函数的定义格式: function add(a,b) { var sum = a+b; document.write("两个数的和是:" + sum); // ...

  8. JS中的函数声明和函数表达式

    JS中的函数声明和函数表达式 1. 函数声明定义一个具有指定参数的函数 函数声明提升, 函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用 hoist ...

  9. js中trim函数_30天中的30个Excel函数:03 – TRIM

    js中trim函数 Yesterday, in the 30XL30D challenge, we took a poke at the lazy brother-in-law function -- ...

最新文章

  1. 使用pyjnius和mpxj来读取mpp文件
  2. Linux 下 SVN 添加多个文件的方法
  3. 谈谈Silverlight 2中的视觉状态管理 Part1
  4. 鸿蒙安卓哪个app好,可以放下对华为鸿蒙的担忧了,操作和EMUI相似,能兼容安卓APP - 区块网...
  5. unix grep命令的大致实现
  6. HDU2571:命运(简单dp)
  7. PAT_B_1012_Java(20分)
  8. 藏不住了,这就是阿里 AI 的真正实力!
  9. C++ rand()函数和srand()函数
  10. JWT token生成原理
  11. errorattributes 过时_苹果官方确认:iPhone 5c 已被列为过时产品
  12. 微信分享踩坑:config:invalid signature错误的解决方法
  13. 基于SSM的灾情发布平台
  14. BZOJ5312 冒险 势能分析、线段树
  15. NPOI2.0学习(三)
  16. ETL调优的一些分享
  17. Atitit xml xpath以及mybatis xml mapper脱机解析 目录 1.1. parseStt(String id, Element root) 1 1.2. parseStt
  18. Linux中rz和sz命令用法详解
  19. 华为校招C++开发岗面试经验——软件开发工程师
  20. 如何在阿里云上购买域名并备案Iot studio

热门文章

  1. 税务局向多人追缴资管计划个人所得税
  2. 单片机升降机c语言程序,基于单片机的货运升降机控制系统设计
  3. 附指南原文下载-《GB/T 39725-2020 信息安全技术 健康医疗数据安全指南》解读(二)
  4. PING32内网安全管理系统3.7.24正式发布
  5. C#学习指北:大白话让你C#极速入门
  6. 鸿蒙应用项目分享:我的鸿蒙毕设:基于HarmonyOS的任务看板平台【一】:项目整体介绍
  7. ideal导入第三方架包
  8. AD设计产品,手工贴片样机你不知道的小妙招
  9. 精易四周年限量纪念U盘(全套)
  10. QD75D2控制MR-J3-10A伺服电机