当前位置: 首页 > 科技观察

29个合格前端工程师需要掌握的JavaScript 技能

时间:2023-03-12 06:53:09 科技观察

合格的前端工程师需要掌握的29个JavaScript技能但是,不管怎样,努力让自己变得更强大,是每一个技术人的信心所在。别的不多说,下面开始今天的内容。另外,今天文章中代码对应的详细注释和具体使用方法都放在我的GitHub上,源码见最下方。希望对你的工作和面试有所帮助。1、判断一个对象的数据类型,使用带有闭包的Object.prototype.toString,通过传入不同的判断类型,返回不同的判断函数。一行代码简洁优雅灵活(注意传入类型参数时首字母大写)不推荐使用该函数检测可能生成wrapper类型的基本数据类型,因为call总是会把第一个参数装箱,使基本类型和包装器类型无法区分。2.数组map方法的循环实现使用方法:将selfMap注入到Array.prototype中(下面数组的迭代方法也是如此)。值得一提的是,map的第二个参数是第一个参数回调中的point。如果第一个参数是箭头函数,设置第二个this将没有效果,因为箭头函数的词法绑定。另一个是稀疏数组的处理。HasOwnProperty用于判断当前下标的元素是否存在于数组中。欢迎在评论区交流。3.使用reduce实现数组map方法4.循环实现数组过滤方法5.使用reduce实现数组过滤方法6.循环实现数组的some方法如果执行某个方法的数组是一个空数组,它总是返回false,如果另一个数组的每个方法中的数组是一个空数组,它总是返回true。7、循环实现数组的reduce方法因为可能存在稀疏数组关系,reduce需要保证跳过稀疏元素,遍历正确的元素和下标。8.使用reduce实现数组的flat方法,因为selfFlat依赖于这个点,所以在reduce遍历的时候需要把这个点指定给selfFlat,否则会默认指向一个窗口,会报错.原理就是通过归约遍历数组。当数组的某个元素还是数组时,通过ES6的展开操作符进行降维(ES5可以使用concat方法),数组元素内部可能嵌套数组,需要递归调用selfFlat。同时原生的flat方法支持一个depth参数来表示降维的深度。默认为1,将数组降维一级。传递Infinity会将传递的数组变成一维数组。原理是每次递归将深度参数减1。如果深度参数为0,直接返回原数组。9、实现ES6的Class语法ES6的Class内部是基于寄生组合继承的,这是目前最理想的继承方式。通过Object.create()方法创建一个空对象,并从Object.create()方法的参数中继承空对象,然后让子类(subType)如果原型对象等于空对象,则子类实例的原型可以等于这个空对象,这个空对象的原型就等于父类原型对象(superType.prototype)的继承关系。Object.create()支持第二个参数,它为生成的空对象定义属性和属性描述符/访问器描述符。我们可以为这个空对象定义一个构造函数属性,更符合默认的继承行为,不可枚举,可枚举的内部属性(enumerable:false)。ES6类允许子类继承父类的静态方法和属性,而普通的寄生组合继承只能实现实例间的继承。对于类之间的继承,需要定义额外的方法。这里的Object.setPrototypeOf()用于将superType设置为subType的原型,从而可以从父类继承静态方法和属性。10.函数柯里化用法:柯里化是函数式编程中的一项重要技术,它将一个接受多个参数的函数转换为一系列接受一个参数的函数。函数式编程的另一个重要功能,compose,可以组合函数,组合后的函数只接受一个参数。因此,如果需要接受多个函数,需要使用compose进行函数组合,就需要对函数使用currying。要组成的部分是评估,所以它总是只需要一个参数。再看一个例子:11.函数柯里化(支持占位符)用法:使用占位符可以使柯里化更加灵活,思路是用每一轮传入的参数来填充上一轮占用的位数。如果当前回合的参数包含占位符,它们将被放置在内部存储的数组中。最后,本轮的元素不会填充本轮参数的占位符,只填之前传入的占位符。12.偏函数用法:偏函数的概念类似于柯里化。我个人认为它们的区别在于partial函数会固定传入的几个参数,然后一次性接受剩下的参数,而函数currying会根据函数传入的参数不断返回直到数ofparametersiscured在限制之前满足函数的参数数量。Function.prototype.bind函数是偏函数的典型代表。它接受的第二个参数以绑定函数参数列表前面的参数开头。与bind不同的是,上述函数还支持计费位字符。13、斐波那契数列及其优化使用函数内存来保存前面运算的结果,对于经常依赖前面结果的计算,比如斐波那契数列,可以节省很多时间。缺点是闭包中的obj对象会占用额外的内存。另外,使用动态规划的空间复杂度比前者低,也是推荐的方案。14.函数bind方法的实现实现函数bind方法的核心是将this指针与call绑定,同时考虑其他情况,例如:?当bind返回的函数被new调用到构造函数,绑定值将失效并成为new指定的对象。?定义绑定函数的长度和名称属性(不可枚举属性)。?绑定函数的原型需要指向原函数的原型(实际上绑定函数是没有原型的,而是绑定函数中有一个内部属性[[TargetFunction]]来保存原函数,创建实例的__proto__指向[[TargetFunction]]的原型,这里不能模拟内部属性,所以直接声明一个prototype属性)。15、函数调用方法的实现原理是将函数作为传入的上下文参数(context)的属性来执行。这里使用ES6Symbol类型来防止属性冲突。16.简单CO模块使用:run函数接受一个生成器函数,run函数包裹的生成器函数只要遇到yield关键字就会停止。当后面的yieldpromise成功resolve时,会自动调用next方法执行到下一个yield关键字。最后,只要成功解决了一个承诺,就会解决下一个承诺。当所有解析成功后,打印所有解析结果,演变成最常用的async/await语法。17.DebounceLeading进入时是否执行一次,原理是使用的定时器。如果在指定时间内再次触发该事件,则清除上一个定时器,即不执行该函数,重新设置一个新的定时器,直到超过指定时间,该时间自动触发该函数在定时器中。同时通过闭包暴露了一个取消函数,使得外部可以直接清空内部计数器。18.节流类似于防抖功能,不同的是多了一个内部时间戳作为判断,如果一段时间内没有事件触发,则允许触发下一个事件。同时增加尾随选项,表示是否在末尾触发追加时间。19、图片延迟加载getBoundClientRect的实现方法是监听滚动事件(建议对监听事件加限流)。图片加载完成后,会从img标签组成的DOM列表中删除。最后,所有图像都需要解除绑定才能加载监视器事件。实现一个intersectionObserver,实例化IntersectionObserver,让它观察所有的img标签。当img标签进入可见区域时,执行实例化回调,并向回调传递一个入口参数,保存实例观察到的所有元素的一些状态,比如每个元素的边界信息,DOM节点对应于当前元素,当前元素进入可见区域的速率。每当元素进入可见区域时,将真实图像分配给当前img标签并释放其观察。20.new关键字21.实现Object.assign22.实现instanceof的原理是递归遍历右参数的原型链,每次与左参数比较,遍历到原型链的末尾返回false,以及如果找到则返回true。23、私有变量的实现使用Proxy代理所有以_开头的变量,使其无法被外部访问。以闭包形式保存私有变量的缺点是类的所有实例都访问同一个私有变量。闭包的另一种实现,解决了闭包的上述缺点,每个实例都有自己的私有变量。缺点是放弃了类语法的简洁性,放弃了所有特权方法(访问私有变量的方法),存放在构造函数中。通过WeakMap和闭包,在每次实例化时保存当前实例和所有私有变量组成的对象,外部无法访问闭包中的WeakMap。使用WeakMap的好处是当实例没有变量引用时会自动释放,实例保存的私有变量可以减少内存溢出问题。24.ShuffleAlgorithm早期的chrome对小于10个元素的数组使用插入排序,会导致数组乱序,不是真正的乱序,即使最新版的chrome使用了in-place算法,使得排序成为一个稳定的算法,乱序问题仍然没有解决。真正的乱序可以通过shuffle算法实现,shuffle算法分为原位和非原位。图1是一种就地改组算法,无需声明额外的数组即可节省内存使用量。原则是按顺序遍历。数组的元素,随机选择当前元素和后续所有元素之一,进行交换。25、单例模式ES6的Proxy实现的单例模式,拦截了构造函数的执行方法。26.Promisify用法:promisify函数是将回调函数转为promise的辅助函数,适用于error-first风格(nodejs)的回调函数。原理是无论错误优先风格的回调成功还是失败,执行完后都会执行最后一个回调函数。我们需要做的就是让这个回调函数控制Promise的状态。这里也使用proxy来代理整个fs模块,拦截get方法,这样就不用手动用promisify函数包装fs模块的所有方法,更加灵活。27、优雅地处理async/await的使用:不用每次使用async/await都包裹一层try/catch,更加优雅。这是另一个想法。如果你用webpack,你可以写一个loader,分析AST语法树,遇到await语法就自动注入try/catch,这样你连辅助函数都不用用。28、EventEmitteron方法用于注册事件,trigger方法触发事件,实现事件之间的松散解耦,另外增加once和off辅助函数,注册只触发一次的事件和注销事件。29.实现JSON.stringify使用JSON.stringify将对象转换为JSON字符串时,会扭曲一些非法数据类型,主要如下:?如果对象包含toJSON方法,则会调用toJSON。?阵列1。当它具有Undefined/Symbol/Function数据类型时变为null。2.Infinity/NaN的存在也会变成null。?对象1。当属性值是Undefined/Symbol/Function数据类型时,属性和值都不会被转换成字符串。2.如果属性值为Infinity/NaN,则属性值会变为null。?日期数据类型值调用ISOString。?不是数组/对象/函数/日期的复杂数据类型变为空对象。?循环引用引发错误。另外,JSON.stringify还可以传入第二个和第三个可选参数,有兴趣的朋友可以多了解一下。实现代码比较长,这里我直接贴上相应的源码地址JSON.stringify:https://github.com/yeyan1996/practical-javascript/blob/master/json.js文章中的源码地址:https://github.com/yeyan1996/practical-javascript总结以上就是我今天分享给大家的29个JavaScript技巧。如果觉得有用,记得点赞,关注我,分享给你的朋友。也许能帮到他。最后,感谢阅读,祝编程愉快!