手写bind函数
实现bind函数
参考MDN提供的Polyfill方案
Function.prototype.myBind = function(context){
//这里对调用者做一个判断,如果不是函数类型,直接抛异常
if(typeof this !== 'function'){
throw '调用必须为函数'
}
//当我们调用bind函数时,我们可能传了不只一个参数
//如 fun.bind({}, arg1, arg2)
//我们需要把后面的参数拿出来
let args = Array.prototype.slice.call(arguments, 1);
let fToBind = this;
let fNOP = function(){};
let fBound = function(){
return fToBind.apply(this instanceof fNOP ? this : context, args.concat(arguments));
}
if(this.prototype){
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();
return fBound;
}
fBound函数这里有个判断 this instanceof FNOP 这个其实是为了避免一种情况,因为bind函数返回的是一个函数,当我们把这个函数实例化(就是new fun())
根据官方文档 当返回的函数被实例化的时候,this指向会锁定指向该实例,不管我们传入的参数指定this指向。
在下面我们 返回的fBound函数时 继承一个空函数 FNOP, 当返回的函数被实例化之后,this instanceof fNOP 结果为true,从而指定this指向
function a (){}
function b (){}
a.prototype = new b();
//如果我们返回的函数实例化了
let c = new a();
c instanceof b //true
//但是大多数情况我们都是
a instanceof b // false
如果这里明白了,那后面的就简单了,context 参数就是我们手动指定的this指向, 当我们绑定bind时会传递多个参数,执行的时候也会带参数,我们就需要把bind
函数除掉第一个以外的参数和我们调用方式时的参数进行拼接
function foo (){}
//示例中 args 就是指的[arg1, arg2]
//args.concat(arguments) 就是将所有的arg1,arg2...arg4的参数进行拼接
let newFoo = foo.bind({}, arg1, arg2);
newFoo(arg3, arg4);
另外 arguments 参数不要搞混淆了,上面那个获取的是bind时的参数(就是{}, arg1, arg2)
下面的arguments 参数是指的调用时的 (就是 arg3, arg4)
手写bind函数的更多相关文章
- 理解并手写 bind() 函数
有了对call().apply()的前提分析,相信bind()我们也可以手到擒来. 参考前两篇:'对call()函数的分析' 和 '对apply()函数的分析',我们可以先得到以下代码: Functi ...
- 前端面试题整理——手写bind函数
var arr = [1,2,3,4,5] console.log(arr.slice(1,4)) console.log(arr) Function.prototype.bind1 = functi ...
- 优雅手撕bind函数(面试官常问)
优雅手撕bind函数 前言: 为什么面试官总爱让实现一个bind函数? 他想从bind中知道些什么? 一个小小的bind里面内有玄机? 今天来刨析一下实现一个bind要懂多少相关知识点,也方便我们将零 ...
- WPF启动流程-自己手写Main函数
WPF一般默认提供一个MainWindow窗体,并在App.Xaml中使用StartupUri标记启动该窗体.以下通过手写实现WPF的启动. 首先先介绍一下VS默认提供的App.Xaml的结构,如下图 ...
- 理解并手写 call() 函数
手写自己的call,我们要先通过call的使用,了解都需要完成些什么功能? call()进行了调用,是个方法,已知是建立在原型上的,使用了多个参数(绑定的对象+传递的参数). 我们把手写的函数起名为m ...
- 理解并手写 apply() 函数
apply()函数,在功能上类似于call(),只是传递参数的格式有所不同. dog.eat.call(cat, '鱼', '肉'); dog.eat.apply(cat, ['鱼', '肉']); ...
- C++之手写strlen函数
代码: int strlen(const char *str){ assert(str!=NULL); intlen=; while((*str++)!='\0') len++; return len ...
- js面试题之手写节流函数和防抖函数
函数节流:不断触发一个函数后,执行第一次,只有大于设定的执行周期后才会执行第二次 /* 节流函数:fn:要被节流的函数,delay:规定的时间 */ function throttle(fn,dela ...
- 手写Bind
Function.prototype.bind2 = function(context){ var self = this; var args = [].slice.call(arguments,1) ...
随机推荐
- Winform中设置ZedGraph多条Y轴时坐标轴左右显示设置
场景 Winform中实现ZedGraph的多条Y轴(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1001322 ...
- python 提取整个 HTML 节点
有的时候,需要把整个 HTML 节点原封不动地取下来,也就是包括节点标签.节点内容,甚至也包括内容中的空格.各种特殊符号等等. 假设已获取到页面源码,并将其保存在变量 src 中.则可有代码如下: f ...
- uni-app学习(五)好用的插件3
1. uni-app学习(五)好用的插件3 1.1. 分享推广页面 分享推广页面,分享第三方.保存二维码.复制推广地址 模板地址 示例 这个用到的几率还是蛮大的,可以直接拿来修改下用 1.2. 教育A ...
- bat弹出确认或取消窗口
需要在bat脚本里面弹出取消/确认框提示,可以用下面的案例: 示例: @echo off setlocal enabledelayedexpansion set Vbscript=Msgbox(&qu ...
- tushare库:免费的python财经数据接口
tushare官网以及在线文档http://tushare.org/ 安装 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tus ...
- Windows下面startup.bat启动Tomcat偶发死锁问题
Windows下面startup.bat启动Tomcat时,因为日志都打印到了cmd里面,存在偶发卡死Tomcat的问题,该问题确认是Windows系统的问题,而且一直没有解决.解决的办法是把日志重定 ...
- ZooKeeper之服务器动态上下线案例
需求 某分布式系统中,主节点可以有多台,可以动态上下线,任意一台客户端都能实时感知到主节点服务器的上下线. 需求分析 具体实现 先在集群上创建/servers节点 create /servers &q ...
- Windows 局域网内共享
前言 在局域网内,其它成员无需密码就可以访问某台计算机共享的某个磁盘或某个文件夹. 本文记录几个关键点, 共享端:需要共享的计算机 用户端:从共享计算机读取文件的计算机 共享端 开启guest用户 1 ...
- 如何在Etherscan.io 部署ETH以太坊智能合约 如何在15分钟内创建你的加密货币
一.概述 ETH 网络这里就不介绍了,这篇文章主要记录在以太坊主网和测试网络部署一个智能合约,也就是如何发币. 二.部署合约需要的生产工具 准备工具前,建议大家准备个VPN,因为会访问国外网 ...
- 函数arguments讲解
// 总结:1- 函数内部有一个实参 arguments 可以获取所有的实参. //2- arguments是一个伪数组,如果要使用数组的方法, 将它转为真数组 // 3 ...