call,apply,bind的内部原理实现
call
call 方法使用一个函数执行的时候更改本身 this 指向,并传入一个或者多个参数。
var obj = {
name: '$call'
}
function _fun() {
console.log(this.name, ...arguments)
}
_fun.call(obj, 'call1', 'call2', 'call3') // $call call1 call2 call3
内部实现原理:
Function.prototype.$$call = function (context) {
// 第一个参数为 this 指向值,如无则指向 window
context = context || window
// 将本身的函数保存下来,在后面需要执行,这一步 this 的指向已经指向了 context
context.fn = this
// 将后面传入的参数转为数组,取除第一个 this 指向剩下的所有参数
let args = [...arguments].slice(1)
// 执行函数本身,并将参数传入
let result = context.fn(...args)
// 销毁函数,避免作用域污染
delete context.fn
return result
}
apply
apply 方法同 call 一样使用一个函数执行的时候更改本身 this 指向,只是传参的时候只有一个,并且必须是数组(如果call与apply传参类型记不清,可以根据方法的第一个字母来区分,apply -> a(首字母) -> array)。
var obj = {
name: '$call'
}
function _fun() {
console.log(this.name, ...arguments)
}
_fun.apply(obj, ['call1', 'call2', 'call3']) // $call call1 call2 call3
内部实现原理:
Function.prototype.$$apply = function (context) {
// 第一个参数为 this 指向值,如无则指向 window
context = context || window
// 将本身的函数保存下来,在后面需要执行,这一步 this 的指向已经指向了 context
context.fn = this
// 将后面传入的参数转为数组,取除第二个参数
let args = [...arguments][1]
// 如果第二个参数不是对象则报错
if (typeof args !== 'object') {
throw Error('CreateListFromArrayLike called on non-object')
return
}
// 执行函数本身,并将参数传入
let result = context.fn(...args)
// 销毁函数,避免作用域污染
delete context.fn
return result
}
bind
bind 方法与 call 和 apply 不同的点是后续的参数没有要求,但是 bind 会返回一个 this 指向已改变的函数,相同的是第一个参数就是 this 指向值
var obj = {
name: '$call'
}
function _fun() {
console.log(this.name, ...arguments)
}
_fun.call(obj, ['call1'], 'call3')('call2') // $call ["call1"] call3 call2
内部实现原理:
Function.prototype.$$bind = function (context) {
// 取bind执行的时候除第一个后续的所有参数
let args = [...arguments].slice(1)
// 函数本身缓存
let _this = this
// 返回函数
return function () {
// 合并返回函数执行传入的参数
let bindArg = [...args, ...arguments]
// 再次调用时的函数本身执行
return _this.call(context, ...bindArg)
}
}
call,apply,bind的内部原理实现的更多相关文章
- 如何实现new,call,apply,bind的底层原理。
new做了什么? new是用来实例化对象的,当new了一个对象后 1.创建一个新对象 2.将构造函数的作用域赋值给新对象(this指向新对象) 3.执行构造函数里面的代码(为这个新对象添加属性) 4. ...
- JavaScript内置一些方法的实现原理--new关键字,call/apply/bind方法--前戏
new关键字,call/apply/bind方法都和this的绑定有关,在学习之前,首先要理解this. 一起来学习一下this吧 首先.this是一个对象. 对象很好理解,引用类型值,可以实现如th ...
- 前端面试 js 你有多了解call,apply,bind?
函数原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this 关键字密切相关,相当一部分人对它们的理解还是比较浅显,所谓js基础扎实,绕不开这些基础 ...
- 原生JS实现call,apply,bind函数
1. 前言 使用原生JS实现call和apply函数,充分了解其内部原理.call和apply都是为了解决改变this的指向.作用都相同,只是传参的方式不同.除了第一个参数外,call可以接受一个参数 ...
- call(),apply(),bind()与回调
1.call(),apply(),bind()方法 JavaScript 中通过call或者apply用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定 ...
- javascript-this,call,apply,bind简述2
上节我们一起研究了this这个小兄弟,得出一个结论,this指向调用this所在函数(或作用域)的那个对象或作用域.不太理解的朋友可以看看上节的内容,这次我们主要探讨一下call(),apply(), ...
- 前端JS面试题汇总 Part 3 (宿主对象与原生对象/函数调用方式/call与apply/bind/document.write)
原文:https://github.com/yangshun/front-end-interview-handbook/blob/master/questions/javascript-questio ...
- 你不知道的JavaScript--Item9 call(),apply(),bind()与回调
1.call(),apply(),bind()方法 JavaScript 中通过call或者apply用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定 ...
- js 中arguments,call,apply,bind的使用
//对于 arguments和this, 每个函数都有自己独有的arguments和this, 且不进行链式查找 //arguments是什么? //答:1:arguments是收到的实参副本 //2 ...
随机推荐
- java实现第七届蓝桥杯取球博弈
题目9.取球博弈 取球博弈 两个人玩取球的游戏. 一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目. 如果无法继续取球,则游戏结束. 此时,持有奇数个球的一方获胜. 如果两 ...
- java实现第五届蓝桥杯锦标赛
锦标赛 这题小编能力有限,还望大佬解决 题目描述 如果要在n个数据中挑选出第一大和第二大的数据(要求输出数据所在位置和值),使用什么方法比较的次数最少?我们可以从体育锦标赛中受到启发. 如图[1.pn ...
- Volcano火山:容器与批量计算的碰撞
[摘要] Volcano是基于Kubernetes构建的一个通用批量计算系统,它弥补了Kubernetes在“高性能应用”方面的不足,支持TensorFlow.Spark.MindSpore等多个领域 ...
- EasyARM-iMX257 linux两年前的笔记
我依然清晰的记得刚拿到Imx283 257的情景,兴奋中充满忧虑,对操作系统的概念只知一二,不知三四!!周立功出品的资料我一直觉得是比较精品的,同样这款iMX283配套的文档资料(v1.04)也是比较 ...
- Python脚本批量修改服务器密码
搭建环境 centos 7.4 使用脚本 python 批量修改connect用户的密码 生成密码为随机密码 保存为xls文档 passwd_chang #!/usr/bin/env python ...
- 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...
- Autoware 标定工具 Calibration Tool Kit 联合标定 Robosense-16 和 ZED 相机!
一.安装 Autoware & ZED 内参标定 & 外参标定准备 之前的这篇文章:Autoware 进行 Robosense-16 线雷达与 ZED 双目相机联合标定! 记录了我用 ...
- C#9.0 终于来了,您还学的动吗? 带上VS一起解读吧!(应该是全网第一篇)
一:背景 1. 讲故事 好消息,.NET 5.0 终于在2020年6月10日发布了第五个预览版,眼尖的同学一定看到了在这个版本中终于支持了 C# 9.0,此处有掌声,太好了!!! .Net5官方链接 ...
- Tftp文件传输服务器(基于UDP协议)
一个简单的UDP服务端与客户端 服务端: from socket import * #创建套接字 udp_server = socket(AF_INET,SOCK_DGRAM) msg_server ...
- Right turn【模拟+标记】
Right turn 题目链接(点击) frog is trapped in a maze. The maze is infinitely large and divided into grids. ...