实现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函数的更多相关文章

  1. 理解并手写 bind() 函数

    有了对call().apply()的前提分析,相信bind()我们也可以手到擒来. 参考前两篇:'对call()函数的分析' 和 '对apply()函数的分析',我们可以先得到以下代码: Functi ...

  2. 前端面试题整理——手写bind函数

    var arr = [1,2,3,4,5] console.log(arr.slice(1,4)) console.log(arr) Function.prototype.bind1 = functi ...

  3. 优雅手撕bind函数(面试官常问)

    优雅手撕bind函数 前言: 为什么面试官总爱让实现一个bind函数? 他想从bind中知道些什么? 一个小小的bind里面内有玄机? 今天来刨析一下实现一个bind要懂多少相关知识点,也方便我们将零 ...

  4. WPF启动流程-自己手写Main函数

    WPF一般默认提供一个MainWindow窗体,并在App.Xaml中使用StartupUri标记启动该窗体.以下通过手写实现WPF的启动. 首先先介绍一下VS默认提供的App.Xaml的结构,如下图 ...

  5. 理解并手写 call() 函数

    手写自己的call,我们要先通过call的使用,了解都需要完成些什么功能? call()进行了调用,是个方法,已知是建立在原型上的,使用了多个参数(绑定的对象+传递的参数). 我们把手写的函数起名为m ...

  6. 理解并手写 apply() 函数

    apply()函数,在功能上类似于call(),只是传递参数的格式有所不同. dog.eat.call(cat, '鱼', '肉'); dog.eat.apply(cat, ['鱼', '肉']); ...

  7. C++之手写strlen函数

    代码: int strlen(const char *str){ assert(str!=NULL); intlen=; while((*str++)!='\0') len++; return len ...

  8. js面试题之手写节流函数和防抖函数

    函数节流:不断触发一个函数后,执行第一次,只有大于设定的执行周期后才会执行第二次 /* 节流函数:fn:要被节流的函数,delay:规定的时间 */ function throttle(fn,dela ...

  9. 手写Bind

    Function.prototype.bind2 = function(context){ var self = this; var args = [].slice.call(arguments,1) ...

随机推荐

  1. 开源工作流引擎 Workflow Core 的研究和使用教程

    目录 开源工作流引擎 Workflow Core 的研究和使用教程 一,工作流对象和使用前说明 二,IStepBuilder 节点 三,工作流节点的逻辑和操作 容器操作 普通节点 事件 条件体和循环体 ...

  2. linux 环境下部署 Asp.Net Core 项目 访问 oralce 数据库

    1.ASP.NET Core 是一个跨平台的高性能开源框架,可以部署到Linux上,那项目部署在Linux上有哪些好处呢? 1.linux硬件需求小,大部分版本免费,成本低. 2.linux的用户管理 ...

  3. FCC-学习笔记 Convert HTML Entities

    FCC-学习笔记  Convert HTML Entities 1>最近在学习和练习FCC的题目.这个真的比较的好,推荐给大家. 2>中文版的地址:https://www.freecode ...

  4. vue--购物车案例(小知识点总结)

    Html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  5. leetcode之求众数

    求众数 给定一个大小为 n 的数组,找到其中的众数. 你可以假设数组是非空的,并且给定的数组总是存在众数. 示例 1: 输入: [3,2,3] 输出: 3 示例 2: 输入: [2,2,1,1,1,2 ...

  6. Nginx01(Nginx简介)

    一:序言 Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的.从2004年发布至今,凭借开源的力量,已经接近成熟与完善. 二:Nginx常用功能 1.Http代理 ...

  7. k8s Ingress和ingress控制器

    ingress架构图简介 我们知道service的表现形式为IP:PORT,即工作在第四层传输层(TCP/IP层),那么对于不同的URL地址经常对应用不同的后端服务或者虚拟服务器,这些应用层的转发机制 ...

  8. [小程序]微信小程序获取input并发送网络请求

    1. 获取输入框数据wxml中的input上增加bindinput属性,和方法值在js部分定义与之对应的方法,只要在输入的时候,数据就会绑定调用到该方法,存入data属性变量中 2. 调用get请求发 ...

  9. Windows远程连接其他主机

    一.远程主机开启允许被远程连接 1. 右键计算机 --> 属性 --> 远程设置 2. 默认是不允许远程桌面的, 在这里我们勾选开启 3. 远程主机设置完成 二.客户机连接设置 1. wi ...

  10. jquery实现一些小动画二

    jquery实现一些小动画二 jquery实现拖拽功能 <!DOCTYPE html> <html lang="en"> <head> < ...