当前位置: 首页 > 后端技术 > Node.js

阿里面试后对函数本质的理解

时间:2023-04-03 20:55:06 Node.js

阿里面试后对函数本质的理解写在前面环境:阿里的在线编程系统,可以让面试官在线测试面试官的编程能力。考点:编程和理论。编程:分为技术自驱动、异步操作、编程风格(小颗粒)、变量作用域、DOM操作等理论:性能优化、浏览器运行机制、协议/标准等应用是基础编写一个好的程序。(参考《第二步:开发人员、开发工程师》五级开发人员技能培训《了解变量、逻辑和函数的含义》)一个问题怎么写信号量?(参考一个关于Promise应用的面试题)那么如何写一个信号量呢?我们先发散一下思路:promise,yield,async/await(ES7)。好了,既然有了技术要点,接下来我们应该选择哪种方法呢?你不妨选择Promise来与其他方法进行比较。对比技术点,看到async/await是ES7的特性,新一代的老大,Promise没用?(参考Async/Await取代Promise的6个原因)那我们看看还有没有救赎的空间(对promise有一些感触)?2.错误处理文章中的错误处理点是说“Async/Await允许try/catch同时处理同步和异步错误。在下面的promise例子中,try/catch无法处理JSON.parse错误,因为它在Promise中。我们需要使用.catch,所以错误处理代码非常冗余。而且,我们实际的生产代码会更复杂。”我们认为问题的根源应该是每一步都需要catch,所以把then里面的函数放到一个数组中,然后递归运行就可以解决这个问题。(另外参考Toxicity:这些关键字有毒据说eval加上try/catch对性能有一定影响)3.条件语句说“需要获取数据,然后决定是直接返回还是继续根据返回的数据获取更多数据。”我们可以通过reject('')来妥善解决,记住最后一定要有一个catch((err)=>console.log(''))。等等,这和上面的有冲突(每一步都要抓住)。这样,又用装饰器模式对函数进行了一次包装。4、《你可能遇到过这样的场景,调用promise1,用promise1返回的结果调用promise2,再用两者的结果调用promise3》一文中提到的中间值。我们使用观察者模式来解决。6、调试篇提到“最后也是很重要的一点,async/await可以让代码调试更简单,有两个原因让调试Promise非常痛苦”。我们也使用递归,把要执行的函数放到一个数组中解析。找到Promise的几大缺点的补偿措施后,就可以编码实现了。(当然我们还是要拥抱新特性)变量命名为exportfunctionsignalLamp(singalArr){}大家都知道,相对于typeScript,JS是dynamic+weak类型(dynamic和weak没有关系)。那么变量命名需要在表达清晰逻辑的同时携带变量类型。好的代码就是通过命名,让用户尽可能的理解和使用。(毕竟同时维护大量的文档和代码是很困难的。)总结起来就是:驼峰+逻辑+类型。参数使用vardoSomething=function(obj){var_adapter={name:'xioaming',title:'xiaoming',age:24,color:'pink',size:100}for(variin_adapter){_adapter[我]=对象[我]||_适配器[i];}//dosomething}exportfunctionsignalLight(data){constsign=data.slice();}传入的参数尽量反汇编,防止用户传递的参数属性改变。(当属性较多时,考虑使用适配器方式)变量的使用尽量保证函数是纯函数。对于传递参数给deepClone/slice,不修改外部变量。函数声明exportfunctionsignalLamp(singalArr){functiontic(singal,time){return()=>newPromise((res)=>setTimeout(()=>{console.log(singal);res();},时间));}constrawArr=singalArr.slice();}函数的声明/定义有A:functiontest(){};B:consttest=function(){};C:consttest=()=>{}那么它们有什么区别吗?方法A:函数会被提升,也就是作用域内任何地方都可以使用。知道了这一点,我们可以得出一个结论:使用这种方法的函数一定是纯函数。B/C方式:不提升功能。这种方法一般定义了一个不纯函数,对不纯函数(这里指依赖于外部的变量)的提升是没有意义的。因为它取决于上下文,即调用变量的初始化。C方法:C方法是箭头函数,这不免让我们思考为什么箭头函数没有functiontest(){}这样的定义方法会有所改进?答案是箭头函数本身的特性(this指向依赖的词法/静态作用域),使得箭头函数的提升没有意义。函数使用exportfunctionsignalLamp(singalArr){functiontic(singal,time){return()=>newPromise((res)=>setTimeout(()=>{console.log(singal);res();},时间));}constrawArr=singalArr。片();constlampArr=rawArr。reduce(function(prev,item){returnprev.concat([tic(item,1000)]);},[]);conststep=function(iterator){if(iterator===lampArr.length){returnstep(0);}else{return()=>lampArr[iterator]().然后(步骤(++迭代器));}}step(0)();}singalLamp(['red','green','yellow']);函数主要有两个用途:闭包闭包的本质是(对共享变量的操作,典型应用是观察者模式/备忘录模式)公共封装和复用。(当我们不需要复用一段逻辑时,我们将其写成函数的动机是:细粒度逻辑)性能优化在web开发过程中,可以优化性能的方面有很多,作者在这里介绍几个符合本文主题的优化方法。也就是js的高性能代码编写(指编写高性能的JS代码),这里简单说几句:i++和++i使用前缀自增表达式,也能带来不小的性能提升。(++i而不是i++)闭包虽然上面介绍了闭包的实用性,但是还是要尽量避免。和removedom一样被诟病。(垃圾回收问题,内存)const和let就let而言,它的使用场景应该比较少,我们只会在循环(for,while循环)和少量必须重新定义的变量中使用。猜想:就执行效率而言,const由于其不可重赋值的特性,可以在语法静态分析方面做更多的优化,从而获得更高的执行效率。(参考阿里FED博客ES6你可能不知道的事情-基础知识)综上所述,写好项目需要兼容性、性能、安全等,写好功能需要设计模式和解耦需求。写好一个函数,需要考虑['比较技术点','变量命名','参数用法','函数声明','函数用法'].join('+');其他个人博客欢迎交流,共同成长