1. 首页

这些手写代码会了吗?骚年

从略带银丝的头发和干净利落的步伐我察觉到,面前坐着的这个面试官有点深不可测。我像往常一样,准备花 3 分钟的时间给面试官来一套昨天晚上精心准备的自我介绍。我自信且得意的诉说着对过往项目所付出的心血,所做的优化取得了怎样的成果,为公司提高了多少的收入。。。

显然,面试官对我说的数字很感兴趣,嘴角微微上扬,经过了一番细节的探讨和技术的对线后。面试官拿出了一张纸。

手写代码。

注重基础的面试官是靠谱的,为了征服他,我一边讲解着实现原理一边写出了代码。

手写 call

call 和 apply 的区别:call 方法接收的是一个参数列表,apply 方法接收的是一个包含多个参数的数组。

  • 1.context 存在就使用 context,否则是 window
  • 2.使用 Object(context)context 转换成对象,并通过 context.fnthis 指向 context
  • 3.循环参数,注意从 1 开始,第 0 个是上下文,后面才是我们需要的参数
  • 4.将参数字符串 pushargs
  • 5.字符串和数组拼接时,数组会调用 toString 方法,这样可以实现将参数一个个传入,并通过 eval 执行
  • 6.拿到结果返回前,删除掉 fn

Function.prototype.call = function(context) { context = context ? Object(context) : window; context.fn = this; let args = []; for (let i = 1; i < arguments.length; i++) { args.push('arguments['+ i +']'); } let res = eval('context.fn('+ args +')'); delete context.fn; return res; }

手写 apply

  • 1.apply 无需循环参数列表,传入的 args 就是数组
  • 2.但是 args 是可选参数,如果不传入的话,直接执行

Function.prototype.apply = function(context, args) { context = context ? Object(context) : window; context.fn = this; if (!args) { return context.fn(); } let res = eval('context.fn('+ args +')'); delete context.fn; return res; }

手写 bind

  • 1.bind 的参数可以在绑定和调用的时候分两次传入
  • 2.bindArgs 是绑定时除了第一个参数以外传入的参数,args 是调用时候传入的参数,将二者拼接后一起传入
  • 3.如果使用 new 运算符构造绑定函数,则会改变 this 指向,this 指向当前的实例
  • 4.通过 Fn 链接原型,这样 fBound 就可以通过原型链访问父类 Fn 的属性

Function.prototype.bind = function(context) { let that = this; let bindArgs = Array.prototype.slice.call(arguments, 1); function Fn () {}; function fBound(params) { let args = Array.prototype.slice.call(arguments) ; return that.apply(this instanceof fBound ? this : context, bindArgs.concat(args)); } Fn.prototype = this.prototype; fBound.prototype = new Fn(); return fBound; }

手写 new

  • 1.Constructor 就是 new 时传入的第一个参数,剩余的 arguments 是其他的参数
  • 2.使用obj.__proto__ = Constructor.prototype 继承原型上的方法
  • 3.将剩余的 arguments 传给 Contructor ,绑定 this 指向为 obj,并执行
  • 4.如果构造函数返回的是引用类型,直接返回该引用类型,否则返回 obj

const myNew = function() { let Constructor = Array.prototype.shift.call(arguments); let obj = {}; obj.__proto__ = Constructor.prototype; let res = Constructor.apply(obj, arguments); return res instanceof Object ? res : obj; }

手写 instanceOf

  • 1.在 left 的原型链中层层查找,是否有原型等于 prototype
  • 2.确定边界条件,如果 left === null,即找到头没找到返回 falseright === left,即找到返回 true
  • 3.left = left.__proto__,不停的向上查找

const myInstanceof = function(left, right) { right = right.prototype; left = left.__proto__; while (true) { if (left === null) { return false; } if (right === left) { return true; } left = left.__proto__; } }

Js中文网 – 前端进阶资源教程 www.javascriptC.com,typescript 中文文档
一个帮助开发者成长的社区,你想要的,在这里都能找到

手写 Object.create

  • 新建一个空的构造函数 F ,然后让 F.prototype 指向 obj,最后返回 F 的实例

const myCreate = function (obj) { function F() {}; F.prototype = obj; return new F(); }

掘金尾图.png

作者:童欧巴
链接:https://segmentfault.com/a/1190000023471270

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「画漫画的程序员」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:这些手写代码会了吗?骚年

链接:https://www.javascriptc.com/4256.html

« LeetCode 122. 买卖股票的最佳时机 II
如何使用Vue3重构你的Vue2项目?»
Flutter 中文教程资源

相关推荐

QR code