当前位置: 首页 > Web前端 > JavaScript

这些功能在js中真是卧龙藏凤

时间:2023-03-27 02:01:12 JavaScript

JavaScript的诞生背景是在互联网发展初期,也就是没有JavaScript的时候,浏览器端的某些表单验证只能发送到服务器端执行的一面。那时,人们还在用速度只有28.8kbit/s的“猫”上网。速度实在是太慢了,实在是让人抓狂。想象一下,当你填写了一个表单并点击提交后,经过漫长的30秒等待,服务器终于返回一个必填字段为空,那么你将...Netscape,当时处于技术创新的最前沿公司决定开发一种客户端语言来弥补这一缺陷。在该公司工作的布伦丹·艾奇(BrendanEich)开始着手开发和设计。由于当时时间紧,加上个人爱好,老板只用了十天时间就设计出了这门语言。当时Netscape称之为LiveScript,但当时Sun的Java语言如火如荼。Netscape在发布前夕将LiveScript更名为JavaScript,以利用媒体对Java的炒作。这和我们的开发过程很像:不管怎么实现,反正今天上线!正是因为设计时间短,对语言的一些细节缺乏严谨的考虑,JavaScript编写的程序长期被吐槽。如果BrendanEich预见到他设计的JavaScript将在全球拥有数百万学习者,成为互联网最流行的编程语言,他会不会多花一点时间?今天我们就来看看JavaScript中的卧龙凤雏。请关注我的公众号,从零手写精简Vue2/Vue3,从零手写Promise完整源码,从零使用typescript手工制作轮子包axios,教你搭建node+egg项目等优质资源。赶快关注公众号,发送“1024”获取吧!!全局变量JavaScript对全局变量的依赖是一个特别糟糕的特性。许多编程语言都允许拥有全局变量,而在JavaScript中,允许处处依赖全局变量。比如我用脚本导入a、b、c这三个文件后,我可以直接在自己的文件d中使用其他文件声明的全局变量。自己的d文件会有一种困惑:这个全局变量从哪里来,有问题去哪里排查。另外,如果在d文件中声明了与该全局变量同名的变量,则会被覆盖,导致无法在后面的文件中使用前三个文件中定义的同名全局变量。后来导入。还有这些定义全局变量的方法:直接在最顶层安排一个var语句,没有任何作用:varfoo='foo'直接给全局对象增加一个属性。在浏览器端,全局对象命名为window:window.foo='foo'直接使用未声明的变量,称为隐式全局变量:foo='foo'所以在实际开发中,一定要避免使用全局变量,使用局部变量.例如使用立即调用函数并开启严格模式的形式:(function(){'usestrict'//这里的变量会变成局部变量//开启严格模式将无法赋值对未声明的变量varfoo='foo'})()scopeJavaScript的语法是从C派生出来的,因此也有块语法。例如,在if之后,可以使用大括号将多个语句组成一个代码块。理论上,这个块中声明的变量应该对外界不可见。但是,不在JavaScript块中。也就是说,JavaScript采用了这样的块语法,但不提供块级作用域。这让具有其他编程语言经验的程序员感到惊讶。ES6出现后,出现了用let关键字声明变量的操作。使用let可以避免这种错误。所以我们在实际开发中应该始终使用let而不是var。自动分号插入JavaScript有一种机制,总是尝试自动插入分号来修复有问题的程序。但是不要依赖它,它可以掩盖更严重的错误。因为它有时会不恰当地插入分号。例如:functiongenObj(){return{status:'ok'}}这似乎返回一个包含status成员的对象,但实际上返回一个undefined。因为JavaScript的自动分号插入机制在return后加了一个分号,运行这行代码也没有报错。把花括号的{和return放在同一行就可以避免这种问题:functiongenObj(){return{status:'ok'}}意思是行尾不加分号,但不能解释当这一行中有一对未闭合的标点符号时不会自动插入分号。我们来看看上面的自执行函数:vara=(function(){return'a'})()()//common.js:5UncaughtTypeError:(intermediatevalue)(...)isnotafunction立即报错。我们的本意是将函数调用的返回值立即赋值给a变量,然后进行其他操作,但是没有在第三行末尾插入分号,JavaScript认为这应该是一个延续调用。为了验证我们的想法,我们把这个立即调用函数的返回值改成一个函数:vara=(function(){returnfunction(){console.log(1)return'a'}})()()此时不报错,打印出1。所以在实际开发中,我们要时刻加分号。但是因为没有分号看起来很简洁,所以很多开发者都不写分号。和Vue源码一样,没有分号,所以我们只需要在某些JavaScript自动插入分号且容易出错的地方手动添加分号即可。我们只需要记住在符号“+”、“-”、“*”、“/”、“(”、“[”的开头前加一个分号即可。typeoftypeof运算符返回一个值,用于标识其操作数字符串的类型。例如:typeof98//numbertypeof'q'//string但不好的是:typeofnull返回对象而不是null。更不正常的是,检测null的方式很简单:val===null所以在检测对象类型的时候,typeof无法返回一个比较准确的介于null和object之间的类型字符串,所以在检测对象类型的时候需要判断之前是否为空值:if(val!==null&&typeofval==='object'){//dosomething}加号运算符加号运算符通常是错误的常见来源。可以用于加法运算,也可以用于字符串的拼接,但是执行什么样的结果完全取决于参数No的类型。如果其中一个操作数是字符串,他也会将其他参数为字符串进行操作并返回。只有当两个操作数都是数字时才进行求和运算,否则两个操作数将被转换成字符串进行拼接。如果您计划使用+运算符进行加法运算,请确保两个操作数都是数字。否则,会出现意想不到的错误。==和=====和===就像邪恶的双胞胎。前者比较两个操作数所代表的值是否相等,但不比较它们的类型。后者是严格比较,在比较值时先进行类型匹配。如果两个操作数的类型不同,它们会试图强制转换它们值的类型,转换规则复杂且难以记忆。这里有一些有趣的例子:console.log(''==0)//trueconsole.log(0=='')//trueconsole.log('0'==0)//trueconsole.log(false=='0')//trueconsole.log([]==![])//trueconsole.log(![]==![])//true所以总是在开发中使用===来避免许多意想不到的错误,除非你确切知道两边的操作数是同一类型,比如使用typeof时:typeof'a'=='string'总结由于JavaScript的诞生背景,有很多奇怪的特性。以上只是这些功能的冰山一角。称其为卧龙卧凤也不为过,但这并不影响它成为流行语言的趋势。经过近几年web的蓬勃发展,人们有了一套规避它们的方案。即使一路修修补补,JavaScript也已成为一把令人向往的利剑。再加上typescript和一些辅助工具(如ESLint)的出现,JavaScript生态繁荣,一统天下指日可待。凡是能用js实现的,最终都会用js实现(开玩笑,王者峡谷没有菜鸟英雄,只有菜鸟召唤师)。另:文中知识点如有表述不当或错误之处,欢迎留言批评指正,共同进步!