IT学习网是免费的终身在线学习平台,现在主要提供IT(互联网)方面的教程,博客等方面的内容
主页 > 前端 > > 正文

儿童编程学习前端开发岗位面试中常考的源代码实现

来源:IT学习网整理 发布时间:2020-02-14 18:55 标签:开发实现前端源代码中常岗位面试
浏览:
手动撸个call/apply/bind,实现call来看下call的原生表现形式:如果一个函数作为一个对象的属性,那么通过对象的.运算符调用此函数,this就是此对象;apply和call实现类似,只是传入的参数形式是数组形式"/>前端开发岗位面试中常考的源代码实现

前端开发前端导航工具/手册更多栏目

折扣返利

网站投稿

书籍/周边

站内搜索

fly63前端网

提交

我要投稿

前端开发岗位面试中常考的源代码实现

时间: 2019-08-08阅读: 166标签: 面试

手动撸个call/apply/bind实现call

来看下call的原生表现形式:

function test(arg1, arg2) { console.log(arg1, arg2) console.log(this.a, this.b) } run.call({ a: 'a', b: 'b' }, 1, 2)

好了,开始手动实现我们的call2。在实现的过程有个关键:

如果一个函数作为一个对象的属性,那么通过对象的.运算符调用此函数,this就是此对象

let obj = { a: 'a', b: 'b', test: function (arg1, arg2) { console.log(arg1, arg2) // this.a 就是 a; this.b 就是 b console.log(this.a, this.b) } } obj.test(1, 2)

知道了实现关键,下面就是我们模拟的call:

Function.prototype.call2 = function(context) { if(typeof this !== 'function') { throw new TypeError('Error') } // 默认上下文是window context = context || window // 保存默认的fn const { fn } = context // 前面讲的关键,将函数本身作为对象context的属性调用,自动绑定this context.fn = this const args = [...arguments].slice(1) const result = context.fn(...args) // 恢复默认的fn context.fn = fn return result } // 以下是测试代码 function test(arg1, arg2) { console.log(arg1, arg2) console.log(this.a, this.b) } test.call2({ a: 'a', b: 'b' }, 1, 2) 实现apply

apply和call实现类似,只是传入的参数形式是数组形式,而不是逗号分隔的参数序列。

因此,借助es6提供的...运算符,就可以很方便的实现数组和参数序列的转化。

Function.prototype.apply2 = function(context) { if(typeof this !== 'function') { throw new TypeError('Error') } context = context || window const { fn } = context context.fn = this let result if(Array.isArray(arguments[1])) { // 通过...运算符将数组转换为用逗号分隔的参数序列 result = context.fn(...arguments[1]) } else { result = context.fn() } context.fn = fn return result } /** * 以下是测试代码 */ function test(arg1, arg2) { console.log(arg1, arg2) console.log(this.a, this.b) } test.apply2({ a: 'a', b: 'b' }, [1, 2]) 实现bind

bind的实现有点意思,它有两个特点:

本身返回一个新的函数,所以要考虑new的情况

可以“保留”参数,内部实现了参数的拼接

Function.prototype.bind2 = function(context) { if(typeof this !== 'function') { throw new TypeError('Error') } const that = this // 保留之前的参数,为了下面的参数拼接 const args = [...arguments].slice(1) return function F() { // 如果被new创建实例,不会被改变上下文! if(this instanceof F) { return new that(...args, ...arguments) } // args.concat(...arguments): 拼接之前和现在的参数 // 注意:arguments是个类Array的Object, 用解构运算符..., 直接拿值拼接 return that.apply(context, args.concat(...arguments)) } } /** * 以下是测试代码 */ function test(arg1, arg2) { console.log(arg1, arg2) console.log(this.a, this.b) } const test2 = test.bind2({ a: 'a', b: 'b' }, 1) // 参数 1 test2(2) // 参数 2 实现深拷贝函数

实现一个对象的深拷贝函数,需要考虑对象的元素类型以及对应的解决方案:

基础类型:这种最简单,直接赋值即可

对象类型:递归调用拷贝函数

数组类型:这种最难,因为数组中的元素可能是基础类型、对象还可能数组,因此要专门做一个函数来处理数组的深拷贝

/** * 数组的深拷贝函数 * @param {Array} src * @param {Array} target */ function cloneArr(src, target) { for(let item of src) { if(Array.isArray(item)) { target.push(cloneArr(item, [])) } else if (typeof item === 'object') { target.push(deepClone(item, {})) } else { target.push(item) } } return target } /** * 对象的深拷贝实现 * @param {Object} src * @param {Object} target * @return {Object} */ function deepClone(src, target) { const keys = Reflect.ownKeys(src) let value = null for(let key of keys) { value = src[key] if(Array.isArray(value)) { target[key] = cloneArr(value, []) } else if (typeof value === 'object') { // 如果是对象而且不是数组, 那么递归调用深拷贝 target[key] = deepClone(value, {}) } else { target[key] = value } } return target }

热门文章

  • C++构造函数初始化列表
    C++构造函数初始化列表

    C++构造函数初始化列表

    构造函数的一项重要功能是对成员变量进行初始化,为了达到这个目的,可以在构造函数的函数体中对成员变量一一赋值,还可以采用 初始化列表 。 C +...

  • 抢占超声医学影像产业学习it的网站C位
    抢占超声医学影像产业学习it的网站C位

    抢占超声医学影像产业学习it的网站C位

    随着全球AI人工智能技术的快速发展与应用 全球医疗领域的智能化 科技化成为大势所趋 据相关资料数据统计 2016年全...

  • “编程从娃娃抓起”:逃得过“奥数” 又
    “编程从娃娃抓起”:逃得过“奥数” 又

    “编程从娃娃抓起”:逃得过“奥数” 又

    您所在的位置: 杭州网 > 新闻中心 > 国内新闻 “编程从娃娃抓起”:逃得过“奥数” 又要被编程套住 2019-03-22 09:18:07;杭州网 新华网 少儿编程火了,打开手机...

  • coreldraw教程网Photoshop iPad完整版本正式上
    coreldraw教程网Photoshop iPad完整版本正式上

    coreldraw教程网Photoshop iPad完整版本正式上

    Photoshop iPad完整版本正式上架苹果App Store...

  • 51自学网ps视频教程走在时尚前端的猎豹
    51自学网ps视频教程走在时尚前端的猎豹

    51自学网ps视频教程走在时尚前端的猎豹

    当消费者发现汽车一味的“大”并不能完全解决出行需求,反而影响了在城市中穿梭的便捷性之后,更加贴合年轻人...

后端

更多 >
后端趣味编程unzip命令 传zip到linux并解压
后端计算机程序设计设置FTP传输软件xftp默认打
后端计算机编程语言有哪些Java实现Linux grep命
后端趣味编程linux安装mysql5.7
后端儿童编程学习linux入门系列8--shell编程入门

工具资源

更多 >