在前端面试中,可能会出现一些手撕模拟实现的题目,这里进行一些记录。

原生api

js中中提供了 call, apply, bind 用于手动指定this的指向

概念

调用 call 和 apply 的对象,必须是一个函数 Function

由于apply()方法(或者call()方法)不仅绑定函数执行时所在的对象,还会立即执行函数

第一个参数,是一个对象, 由该对象调用Function

s.Function.call(obj)
// 相等于 obj.FunctionA.sayHello.call();//不传参数指向全局window对象,输出window.name也就是window
//如果call方法没有参数,或者参数为null或undefined,则等同于指向全局对象。

call 和 apply 的主要作用,是改变对象的执行上下文,并且是立即执行的。它们在参数上的写法略有区别。

bind 也能改变对象的执行上下文,它与 call 和 apply 不同的是,返回值是一个函数,并且需要稍后再调用一下,才会执行。

call(),apply(),bind()都是用来重定义this对象的

这三个函数的第一个参数都是 this 的指向对象;

第二个参数的差别:

call 的参数直接放进去,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,‘n1’, … ,‘n’ )

apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,[‘n1’, …, ‘m’ ])

bind 除了返回是函数以外,它的参数和 call 一样。

当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

var obj = {name:'tzb',age:18,myFunc:function(n, a){console.log(this.name + "年龄" + this.age);console.log(n + "年龄" + a);}
}var db = {name :'zhi',age:22
}
// call apply bind 都是挂到Object上的函数
//1.call
obj.myFunc(); // tzb 年龄18
// obj.myFunc().call()是错误写法 ()表示立即执行函数 myFunc()执行完成之后并没有返回值
obj.myFunc.call(db,'bin',33) // zhi年龄22 /n bin年龄33//2.apply
obj.myFunc.apply(db,['bin',33]) // zhi年龄22  bin年龄33//3.bind
var f = obj.myFunc.bind(db,'bin',33);
// bind返回的是一个函数 加上()才会执行
f();  // zhi年龄22  bin年龄33

模拟实现

bind的模拟实现使用到了 apply ,这里先给出apply的模拟实现

apply
// args传入的需要是一个数组
function myApply(context, args) {if (typeof this !== 'function') {throw new Error('调用者必须是函数');}context = context || window;// 手动给调用者添加一个方法context.fn = this;let res;if (args) {res = context.fn(...args);}else {res = context.fn();}// 获得结果后删除该属性delete context.fn;return res;
}Function.prototype.myApply = myApply;

bind模拟实现

// bind(thisObj, a1, a2, a3);function myBind(...args) {if (typeof this !== 'function') {throw new Error('调用者必须是函数');}const fn = this;const context = args[0] || window;const myArgs = args.slice(1);return function(...newArgs) {fn.apply(context, myArgs.contact(newArgs));}}

上述模拟实现没有考虑bind返回的函数作为构造函数的情况。
在构造函数中,this指向新生成的对象。那么下面这个就不合适了。

  return function(...newArgs) {fn.apply(context, myArgs.contact(newArgs));}

考虑构造函数的情况

// bind(thisObj, a1, a2, a3);function myBind(...args) {if (typeof this !== 'function') {throw new Error('调用者必须是函数');}// this为调用bind的函数对象const fn = this;const context = args[0] || window;const myArgs = args.slice(1);let Temp = function(){};Temp.prototype = fn.prototype;// bind返回的函数 f 作为构造函数时 let f =  function(...newArgs) {return fn.apply(this instanceof f ? this : context, myArgs.contact(newArgs));}// 继承原型链上的属性f.prototype = new Temp();return f;}

js手撕——bind的模拟实现相关推荐

  1. 常见js手撕题及算法总结

    文章目录 实现一下观察者模式 实现一下工厂模式 实现一下单例模式 设计一个lazyMan,实现以下功能: 实现一个简单的EventEmitter 手撕实现原生js的一些方法(call.apply.bi ...

  2. 前端百题斩【015】——快速手撕call、apply、bind

    写该系列文章的初衷是"让每位前端工程师掌握高频知识点,为工作助力".这是前端百题斩的第15斩,希望朋友们关注公众号"执鸢者",用知识武装自己的头脑. 在百题斩[ ...

  3. (面试题)面试官为啥总是让我们手撕call、apply、bind?

    引言 上一篇关于<面试官为啥总是喜欢问前端路由实现方式>的文章发布后,发现还是挺受欢迎的.这就给我造成了一定的困惑 之前花了很长时间,实现了一个自认为创意还不错的关于前端如何利用node+ ...

  4. 前端date format_前端面试-手撕代码篇

    前言 在前端面试有一个非常重要的环节,也是面试者最担心的一个环节.对"手撕代码"的考察需要面试者平时总结和积累(临时抱佛脚是不好使的),在这里笔者就自己如何攻破"手撕代码 ...

  5. Python3《机器学习实战》学习笔记(八):支持向量机原理篇之手撕线性SVM

    原 Python3<机器学习实战>学习笔记(八):支持向量机原理篇之手撕线性SVM 置顶 2017年09月23日 17:50:18 阅读数:12644 转载请注明作者和出处: https: ...

  6. 和12岁小同志搞创客开发:手撕代码,做一款声控灯

    机缘巧合在网上认识一位12岁小同志,从零开始系统辅导其创客开发思维和技巧. 项目专栏:https://blog.csdn.net/m0_38106923/category_11097422.html ...

  7. 手撕 MySQL 事务,发生了什么?

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:2 个月的面试亲身经历告诉大家,如何进入大厂? 作者:flyman 链接:https://segmentfaul ...

  8. python 遍历_Python手撕广度优先遍历

    在谈广度优先遍历之前,我们需要知道图是什么. 1.图  图(graph)是表示物件与物件之间关系的数学对象,是图论的基本研究对象,图由节点(node)和边(edge)组成.图分为两种:1.有向图.2. ...

  9. 猿人学第二题,手撕OB混淆给你看(step06-控制流平坦化)

    前情回顾: 猿人学第二题,手撕OB混淆给你看(Step1-开篇) 猿人学第二题,手撕OB混淆给你看(step2-字符串数字回填) 猿人学第二题,手撕OB混淆给你看(step3-函数调用还原) 猿人学第 ...

最新文章

  1. Ubuntu root密码设置
  2. 计算机的硬盘和光盘数,硬盘和光盘属于什么媒体
  3. 由浅入深:自己动手开发模板引擎——置换型模板引擎(一)
  4. 用神经网络分类响尾蛇和牛蛙
  5. SQL Server 2014 Win7 Win10 安装详解 SQL Server 2017 2019 Linux及SQL TSQL ETL实用案例
  6. java treemap_Java TreeMap keySet()方法与示例
  7. java 执行顺序混乱_java类执行顺序问题
  8. 包含贴息时如何重算还款计划
  9. 编程学习好去处:35 个快速学习的编程网站
  10. mongodb(分片)
  11. [复变函数]第16堂课 4.4 解析函数零点的孤立性及惟一性定理
  12. SpringBoot整合Sharding-JDBC实现水平分库分表之操作公共表
  13. 前端如何使用mock模拟接口数据
  14. 最美的公式:你也能懂的麦克斯韦方程组
  15. Android EditText身份证等类型
  16. NET 3行代码实现文字转语音功能
  17. 如何应对redis缓存的击穿、穿透和雪崩
  18. 卷积神经网络 神经网络,卷积神经网络基础知识
  19. java swing桌面程序打包成.exe文件
  20. atan函数和atan2函数的区别

热门文章

  1. SpringBoot教程(10) Jackson ObjectMapper使用和常用注解
  2. TinyXml2 不完全使用指南
  3. word文件做一半未响应_Win7的word为什么老是出现未响应?
  4. 关于IDEA开发Post数据报404错误的一种情况
  5. 计算机课打字评课,铁岭小学评课《键盘常识》  郭继岩
  6. 狼山会心法库:掌控「一体共振律」,让你心想事成,梦想成真的秘密
  7. 我要自学网小程序开发
  8. esp32掌控板程序
  9. 学习笔记:MultipartFile中的transferTo方法
  10. MurmurHash算法初探