作者:MahdhiRezvi洗碗的洗碗智慧。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。你可能经常听到一些人抱怨JS很奇怪,有时甚至毫无价值。之所以有这样的想法,是因为他们对JS背后的工作原理了解不多。我也觉得JS处理某些情况的方式与其他语言不同,但这不能怪罪,它只是以自己的方式展示给大家。如果你喜欢一门编程语言,那么你应该想一个一个地理解和掌握它的概念。这里列出了36个JavaScript概念,你需要掌握这些概念才能成为更好的精通JS的前端开发人员。1.调用栈执行我们都知道栈溢出,但是你知道栈溢出是什么原因造成的吗?堆栈溢出与调用堆栈的某些操作错误有关。了解调用栈,可以让你清楚地了解像JS这样的编程语言是如何执行的。2.原始数据类型constfoo="bar";foo.length;//3foo==="酒吧";//true这里,当我们给常量foo赋值bar时,它属于原始类型string。每个人都知道这一点。但是大家有没有想过一个问题,string是一种基本数据类型,怎么调用方法呢?奇怪的?没有。此功能称为自动装箱。每当读取到一个基本类型,JS后台就会创建一个对应的基本封装类型对象,这样我们就可以调用一些方法来操作数据。让我们从上面的例子开始:constfoo="bar";foo.length;//3foo==="酒吧";//true变量foo是一个原始值,它不是一个对象,它不应该有方法。但是JS在里面已经为我们完成了一系列的处理(也就是装箱),这样它就可以调用方法了。实现机制如下:创建一个String类型的实例,并在该实例上调用指定的方法销毁该实例。constfoo=newString("bar");foo.lengthfoo==='bar'foo=null对原始数据类型有了很好的理解,我们应该知道这些“奇怪”的情况是如何发生的,以及它们背后的逻辑。3.值类型vs.引用类型最近,我对JS中“引用传递”的工作原理感到困惑。虽然我知道在C和Java等语言中有“按引用传递”和“按值传递”的概念,但我不确定它在JS中是如何工作的。你知道在JS中赋值给非原始值的变量都有那个值的引用吗?引用指向存储值的内存位置。.vararr1=[1,2,3];vararr2=arr1;arr2.push(10);console.log(arr2);//[1,2,3,10]console.log(arr1);//[1,2,3,10]正如您在上面的示例中看到的,对arr2所做的任何修改也将反映在arr1中。这是因为它们只持有对值对应的内存地址的引用,而不是值本身。通过了解值类型和引用类型的概念,您将更好地理解如何为变量赋值和内存引用。4.强制类型转换的概念主要解释了隐式类型转换和显式类型转换的区别。这是前端开发中为数不多的让JS摸不着头脑的领域之一。对于隐式强制转换的概念尤其如此,它对不同的数据类型有不同的表现。这是JS面试中最常被问到的问题。Number('789')//显式+'789'//隐式789!='456'//隐式9>'5'//隐式10/null//隐式true|0//implicit你已经掌握了类型显式和隐式的转换,恭喜你,你对JS有了更深的理解。5.比较运算符和typeof运算符双重相等和三重相等,它们在大多数情况下表面上看起来是一样的并且给出相同的结果,然而,它们有时可能会引入意想不到的错误。为了理解两兄弟的区别,我们可以使用typeof来查看被比较的值的类型。typeof3//"number"typeof"abc"//"string"typeof{}//"object"typeoftrue//"boolean"typeofundefined//"undefined"typeoffunction(){}//"function"typeof[]//"object"typeofnull//"object"6.JavaScript作用域Scope是JS中很重要的一个坑,JS一直在不断完善它的作用域。根据Wissam的说法,范围的简单定义是编译器在需要时查找变量和函数。了解范围有助于我们有效地使用JavaScript。我们还需要了解全局作用域以及块和函数作用域,也称为词法作用域。JS作用域一开始可能会令人困惑,但是一旦您理解了它的工作原理,使用它就会非常令人兴奋。7.语句和声明JavaScript程序是可执行语句的集合。所谓语句就是一个可执行单元,通过语句的执行,实现一定的功能。通常一条语句占一行,以分号结束。默认情况下,JavaScript解释器按顺序执行语句。如果要改变这种默认的执行顺序,需要使用判断、循环等流程控制语句。我们应该知道statement和statement的区别,这对我们全面理解JS很有帮助。8、ImmediatelyInvokedFunctionExpression和ModuleIIFE:ImmediatelyInvokedFunctionExpression,意思是立即调用的函数表达式,即在函数声明时立即调用该函数。它主要用于避免污染全局范围。后来,引入了ES6模块,提供了一种避免全局范围污染的标准方法,尽管有人认为它不是IIFE的直接替代品。通过了解IIFE和模块,您可以构建更少因全局空间处理不当而导致错误的应用程序。当然,有了模块,我们可以做的更多。大家都说简历里没项目可写,所以给大家找了一个项目,还给了一个【搭建教程】。9.消息队列和事件循环正如MDN文档所说,JavaScript有一个基于事件循环的并发模型,负责执行代码,收集和处理事件,执行队列中的子任务。该模型与其他语言(如C和Java)中的模型有很大不同。在并发模型中,消息队列用于处理最旧的消息。只要有事件发生,它就会被添加到消息队列中。通过理解这些概念,你可以更好地理解JS是如何工作的以及你的代码是如何工作的。10、时间间隔如果你想在JS中有计划地调用一个函数,可以使用下面两个函数:setTimeout允许我们在特定的时间间隔后运行一个函数。setInterval允许我们重复运行一个函数,从一个特定的时间间隔开始,然后以该时间间隔连续重复。这些跟之前的消息队列和事件处理器的概念有些相关。因此,通过了解间隔方法,我们可以了解它们的工作原理并在我们的用例中有效地使用它们。11.JS引擎JavaScript引擎是执行JS代码的计算机程序或解释器。JS引擎可以用多种语言编写。例如,驱动Chrome浏览器的V8引擎是用C++编写的,而驱动Firefox浏览器的SpiderMonkey引擎是用C和C++编写的。要编写高效的代码,您必须了解您正在使用的JS引擎。使用webviews的移动开发者要特别注意这一点。12.位运算位运算将值视为位(0和1),而不是十进制、十六进制或八进制数。按位运算符对此类二进制表示执行运算,但它们返回标准的JavaScript数值。通常,这些操作很少在代码中使用,但它们确实有一些用例。例如,您可以使用它们来查找偶数和奇数值、颜色转换、颜色提取等。通过对这些位运算有扎实的理解,你可以很好地使用像WebGL这样的技术,因为它涉及很多像素操作。13.DOM和布局树我们大多数人都听说过文档对象模型(DOM),但只有少数人对它有深入的了解。你知道你在浏览器中看到的不是DOM吗?而是渲染树,它实际上是DOM和CSSOM的组合。通过了解DOM的工作原理、结构以及页面的呈现方式,我们可以借助JS动态地操作网页。这对于确保我们的应用程序以高标准执行尤其必要。14.类和工厂JavaScript不是一种面向对象的语言。但是,为了模仿OOP属性,使用了构造函数。根据Tania的说法,“JavaScript中的类除了原型和继承的语法糖之外并没有真正提供任何其他东西,因为它们提供了更清晰、更优雅的语法。由于其他编程语言使用类,JS中的类语法使它更容易开发人员在语言之间移动。”工厂函数是返回对象的类或构造函数的函数。按照JS专家EricElliot的说法,“在JavaScript中,任何函数都可以返回一个新对象。如果它不是构造函数或类,则称为工厂函数。”需要两个概念。15.this关键字与apply、call、bind方法个人认为理解this关键字对于一个JS开发者来说是非常重要的。如果不能正确理解,以后开发的项目会经常遇到这个相关的问题。如果对this关键字比较清楚,可以看看apply、call、bind方法,可以解决this指针带来的问题。16.构造函数和“instanceOf”运算符构造函数就像常规函数一样。但它们有很多区别,函数名以大写字母开头,并且只能由new运算符执行。具有OOP开发经验的程序员将熟悉new关键字。为了正确识别对象的类型,我们使用instanceOf运算符。简单来说,它检查一个对象是否是另一个对象的实例。这有助于您了解对象如何相互继承,而继承是通过原型实现的。17.原型这是JS中最令人困惑的概念之一,即使对于拥有十年经验的人来说也是如此。JavaScript中的原型是一种在对象之间共享通用功能的机制。几乎所有JavaScript中的对象都是Object的实例。对象继承了Object.prototype的所有属性和方法。简单来说,原型就是一个对象,JS对象从中继承方法和属性。通过了解原型,您可以构建高效快速的应用程序。18.使用new、Object.create和Object.assign创建对象创建对象的方法有很多种。但是,Metropolis选择了Object.create方法而不是new关键字。这是有原因的,因为在使用Object.create方法时,可以将现有对象用作新创建对象的原型。这使得重用现有对象的属性和功能成为可能,有点像OOP中的继承概念。使用Object.assign方法时,您可以将一个可枚举对象自身的属性从一个或多个源对象复制到目标对象。在这种情况下,目标对象的原型不包含源对象的属性。这是这两种方法的主要区别。通过了解这三种创建对象的方式,您可以根据实际情况适当地使用它们来创建更高效??的程序。19.map、filter、reduce方法这三个方法在数组操作时非常有用。它们可以在Array原型中找到。如果你有一个数组并且想对每个元素做一些事情,那么你可以使用map方法。如果你有一个数组,想通过某种条件过滤一些值,可以使用filter方法。reduce()方法为数组中的每个元素执行您提供的缩减器函数(按升序),将其结果聚合到一个返回值中。一个典型的例子是对一个数组的所有元素求和:letnumbers=[1,2,3,4,5,6]constreduced=numbers.reduce((accumulator,currentValue)=>accumulator+currentValue)console.log(reduced)//21请注意,以上三种方法不会改变原数组的值。20.纯函数、副作用、状态变化这三个概念对于JS开发者来说非常重要,而状态变化对于使用React的开发者尤为重要。纯函数是指返回结果只依赖于它的参数并且在执行过程中没有副作用的函数。函数副作用是指函数被调用时,除了返回函数值外,还会对主调用函数产生额外的影响。有副作用的函数不仅会返回一个值,还会做其他事情,例如:修改一个变量直接修改一个数据结构设置一个对象的成员抛出异常或以错误终止打印到终端或读取给用户输入读取或写入文件在屏幕上绘制状态更改是您更改变量值的地方。如果您对变量进行更改,它可能会影响其他功能,具体取决于变量在更改之前的值。在React环境中,我被建议不要改变状态。21.闭包闭包很难理解。但是一旦你理解了,你就会觉得JS其实还是挺好的。网上有很多资源。你花足够的时间学习闭包,它并不难掌握和理解。使用闭包在内部作用域中访问外部作用域的作用域。每次创建函数时,都会在创建函数时创建JavaScript闭包。22.高阶函数高阶函数是将其他函数作为参数或返回结果的函数。您可以创建只负责一项任务的较小函数,然后在这些较小函数的帮助下构建复杂函数。这也保证了代码的可重用性。23.递归递归是所有编程语言中的一个通用概念。简单的说,递归就是把大问题分解成小问题,然后再解决小问题的方法。尽管递归可能是一个令人困惑的概念,会让您头疼,但通过大量练习,从小问题开始,您可以更好地理解它。24.集合和生成器集合和生成器是ES6中新引入的。新引入的集合有Map、Set、WeakSet和WeakMap。这些集合为我们提供了一些非常方便的操作。了解它们是怎样的至关重要,尤其是对于现代JavaScript。生成器有时很难理解,尤其是对于初学者。生成器允许我们编写可以暂停和重新启动的代码函数,而不会阻塞其他代码的执行,这在JavaScript中是非常不寻常的。25.PromiseJecelyn对Promises的解释如下:“假设你是个孩子。你妈妈向你保证,她下周会给你买一部新手机。”如果你拿到那部手机,你要到下周才能知道。要么你妈妈真的给你买了一部全新的手机,要么她不买是因为她不开心。这算作一个承诺。一个Promise有3种状态,分别是:Pending:不知道能不能拿到手机Fulfilled:妈妈很开心,给你买了新手机Rejected:妈妈不开心,不买了,怎么办你爱?26、异步编程要理解什么是异步编程,首先要积善行,什么是同步编程。同步编程是线程阻塞的,由于JS是单线程的,所以代码会一行行执行。但是使用异步代码,您可以执行一些耗时的任务。当您必须执行多项需要很长时间才能完成的任务时,此功能特别有用。但在某些情况下,即使是需要长时间执行的代码也可能需要同步。在这种情况下,可以使用async/await。27.ES6箭头函数箭头函数是ES6的新特性,是对正则函数的语法替换。不同之处在于箭头函数不绑定到this、arguments、super或new.target关键字。这使得箭头函数在某些情况下是一个不错的选择,而在其他情况下则是一个非常糟糕的选择。所以,不要从一开始就使用箭头函数。您需要根据您的实际情况使用它们。大家都说简历里没项目可写,所以给大家找了一个项目,还给了一个【搭建教程】。28.数据结构无论使用何种编程语言,数据结构都是开发人员应具备的基本知识之一。糟糕的程序员担心代码,好的程序员担心数据结构和它们之间的关系。在数据结构方面,你应该知道链表、队列、栈、树、图和哈希表。29.时间复杂度无论是哪种编程语言,时间复杂度分析都是计算机编程的另一个基础。要构建更好的应用程序,您应该编写更好的解决方案。为此,您需要了解时间复杂度的概念。有时也称为BigO。30.算法这也是计算机基础课程最先要讲授的内容之一。简而言之,算法是实现目标的逐步过程。程序员应该能够从算法的角度看待任何问题。尽管有大量算法和数千个用例,但以下两个是常见的:搜索排序这两个用例对程序员来说是如此常见,以至于至少应该知道实现它们的已知算法。没有硬性规定您应该使用这些算法中的一种,但是这些算法在性能方面是众所周知的并且有据可查。您甚至可以创建自己的算法并将其介绍给世界。如果它比目前已知的算法更好,你可能会成为下一个编程明星31.继承、多态和代码重用JS中的继承可以使用原型来实现。这是因为JS是一种非OOP语言。但是JS通过提供原型继承来提供OOP的一些特性。多态性是一个对象、变量或函数可以采用多种形式的概念。在JS中,很难看到多态的影响,因为在静态类型系统中,多态经典类型更为明显。以上两个概念都可以帮助我们在JS中实现更好的代码复用。32、设计模式设计模式(Designpattern)代表了最佳实践,通常被经验丰富的面向对象软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员在相当长的一段时间内反复试验的结果。33.函数式编程函数式编程是一种编程范式,一种构建计算机程序结构和元素的风格,将计算视为数学函数的评估,避免状态和可变数据的变化。函数式编程需要掌握的几个概念:纯函数不可变引用透明高阶函数34.干净代码原则这是每个开发人员都应该掌握的基本技能,无论他们使用什么编程语言。每种编程语言都有一套独立的良好实践。虽然这些“好”做法是主观的,并且因工作场所而异,但有些做法被认为是“好”的。通过遵循这些编码原则,您可以确保每个人都能阅读和维护您的代码。这也将帮助您和您的团队在应用程序开发过程中顺利协作。35.Destructuringassignment解构赋值运算符是ES6中引入的,非常好用。对于相同的用例,它们比以前的实现更简单、更高效。36.ES2020新特性编程的优点之一是,如果不不断学习,你永远不会成为该领域的专家。编程语言随着时间的推移而发展,因为每个主要版本都引入了额外的新功能。这也意味着您在某个概念上的专业知识可能会在未来10年到期,因为随着版本更新发布了更好的替代方案。这是任何编程语言都非常常见的情况。ES2020发布了几个新特性,包括可选链、空值合并、动态导入等。您必须学习这些新概念才能跟上快速变化的IT世界。掌握一门语言需要多年的经验和时间,但知道掌握什么会让事情变得更容易,我希望这36个概念对你有所帮助。达人的【三通】是小智继续分享的最大动力。本博客如有错误或建议,欢迎达人留言。最后谢谢大家的观看。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。交流有梦想,有干货,微信搜索【大千世界】关注这位凌晨还在洗碗的洗碗智者。本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,里面有完整的测试站点、资料和我的一线厂商访谈系列文章。
