博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模拟实现函数的apply.call.bind函数
阅读量:4129 次
发布时间:2019-05-25

本文共 1802 字,大约阅读时间需要 6 分钟。

apply.call.bind 的作用:都是为了改变函数运行时上下文(this指向)。

三兄弟的区别:

  • 三兄弟接收的第一个参数都是 要绑定的this指向.
  • apply的第二个参数是一个参数数组,call和bind的第二个及之后的参数作为函数实参按顺序传入。
  • bind不会立即调用,其他两个会立即调用。

 

模拟实现函数的call方法

函数定义:call是可以被所有方法调用的,所以需要定义在 Function的原型上。

函数接收参数:绑定函数被调用时只传入第二个参数及之后的参数。

  • 首先context为可选参数,如果不传的话默认上下文是window
  • 接下来给content创建一个fn属性,并将值设置为需要调用的函数
  • 因为call可以传入多个参数作为调用函数的参数,所有需要将参数剥离出来
  • 然后调用函数并将对象上的函数删除
Function.prototype.defineCall = function (context) {  context = context || window;   //第一个参数为undefined或null的时候,那么会转变为window  context.fn = this;   //给context添加一个方法,指向this  let args = [];  args = [...arguments].slice(1);  //首先通过[...xxx]把arguments类数组变成数组,再拿到去除第一个参数的新数组  let result = context.fn(...args);  delete context.fn;  //删除该方法,不然会对传入对象造成污染  return result;}

测试结果:

let sayName = function (age) {  console.log('current name: ' + this.name, "current age: " + age);}let obj1 = {  name: "obj's name"}sayName.defineCall(obj1, 22); //this指向 sayName函数实例// current name: obj's name current age: 22

 

模拟实现函数的apply方法

思路和call是一样的只是传参不同方式而已

// 模拟 apply 方法Function.prototype.defineApply = function (context, arr) {  context = context || window;  context.fn = this;  let args = [...arguments][1];  let result = args ? context.fn(args) : context.fn();  delete context.fn;  return result;}

测试结果:

let obj2 = {  name: ['Tom', 'Johy', 'Joe', 'David']}sayName.defineApply(obj2, [3, 4, 5, 6, 7]);// current name: Tom,Johy,Joe,David current age: 3,4,5,6,7

 

模拟实现函数的bind方法

bind() 方法会创建一个新函数。

//用call、apply模拟实现bindFunction.prototype.bind = function (context) {  let self = this; // 保存函数的引用  return function () { // 返回一个新的函数    // console.log(arguments);    // return self.apply(context, arguments);    return self.call(context, arguments);  }};

测试结果:

let obj = {  name: 'seven'}let func = function () {  console.log(this.name)  //seven}.bind(obj);func('zhangsan', 20);

 

转载地址:http://fiuvi.baihongyu.com/

你可能感兴趣的文章
北京十大情人分手圣地
查看>>
Android自动关机代码
查看>>
Android中启动其他Activity并返回结果
查看>>
2009年33所高校被暂停或被限制招生
查看>>
GlassFish 部署及应用入门
查看>>
iWatch报错: Authorization request cancled
查看>>
iWatch报错: Authorizationsession time out
查看>>
如何运行从网上下载的iWatch项目详细步骤.
查看>>
X-code7 beta error: warning: Is a directory
查看>>
Error: An App ID with identifier "*****" is not avaliable. Please enter a different string.
查看>>
X-code beta 开发iWatch项目,运行没有错误,但是某些操作一点就崩,而且找不错误的原因场景一
查看>>
Xcode 报错: Extra argument in call
查看>>
iTunes Connect 上传APP报错: Communication error. please use diagnostic mode to check connectivity.
查看>>
#import <Cocoa/Cocoa.h> 报错 Lexical or Preprocessor Issue 'Cocoa/Cocoa.h' file not found
查看>>
`MQTTClient (~> 0.2.6)` required by `Podfile`
查看>>
X-Code 报错 ld: library not found for -lAFNetworking
查看>>
Bitcode
查看>>
If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
查看>>
3.5 YOLO9000: Better,Faster,Stronger(YOLO9000:更好,更快,更强)
查看>>
iOS菜鸟学习--如何避免两个按钮同时响应
查看>>