一开始,随着ES6+和Typescript的席卷而来,Javascript的世界已经充满了符号。我觉得如果我现在不努力学习,我就跟不上了。看别人写的代码,就像读天书一样。最近在项目中看到一个功能,Em...call,好家伙!!!为了更高效地搬砖,本章的目的是探索你可能不了解的神奇符号和书写方法。当然,如果你遇到更多奇葩操作,欢迎在评论区留言抢座(不抢也没关系抢^〇^)。(一切都是为了更好的钓鱼,加油!!!)JS解构赋值(写)变量解构赋值是ES6带来的新特性,这东西是个好东西,用起来挺爽的,总之很好的!!!相信大家都很熟悉了,这里就不解释它的基本用法了。下面我们就来看看下面这些有趣的写作方法,看看能不能给你一些新的体验,学习一些新的技巧。在控制台方法中调试代码是一个非常关键的环节。虽然现在的调试方式多种多样,但控制台方式是最简单、使用起来最实用的。不过不知道大家会不会一时觉得写console.log()很繁琐呢?那么你可以尝试这样使用它:'危险的');用它来自己品尝和食用怎么样?(T_T)vararr=['L','O','V','E'];var{0:l,1:o,2:v,3:e}=arr;console.log(l,o,v,e);//LOVE获取数组的第一项和最后一项vararr=['first','second','last'];var{[0]:first,[arr.length-1]:last}=arr;console.log(first,last);//firstlast叫什么?这才叫不走寻常路!!!等等,我们可以在这里找到一点知识,例如:vararr=['first','second','last'];var{[arr.length<=1?0:arr.length-1]:last}=arr;console.log(last);//lastEm...这里面可以使用表达式,所以可以做很多事情吧?嘿嘿!!!字符串也是解构的var[a1,a2,a3,a4]='YYDS';console.log(a1,a2,a3,a4);//YYDSvar[lastname,...name]='OrangeSBFrontend';console.log(lastname,name);//Orange,person,front-end,虽然使用场景可能很少,但说不定哪天有用。可变价值交换varx=1;变量y=2;[x,y]=[y,x];没什么好说的,反正不用再定义临时变量了。defaultvalue的默认值是我在项目中实际看到的,大致简化成这样,请仔细阅读。varupperValue='';//接口的值let{value:newValue=upperValue||'之前的接口没有值'}={value:undefined};//另一个接口可能返回的值console.log(newValue)莎士比亚说过:一千个人眼中有一千个哈姆雷特。(一千个人眼中有一千个哈姆雷特)我想写代码也是一样。..(⊙o⊙)模板字符串的标签模板(fn``)console.log`橙子`;//['橙子']//等同于console.log(['橙子']);//['Orangesomeone']这其实是函数的一种特殊调用形式。虽然你这辈子可能用不到,但也不排除别人会写出来。知己知彼。更多用法请点击文档。值分隔符(_)ES6中允许的值使用下划线(_)作为分隔符。有了这个东西,你再也不用为数零光环而烦恼了。让num1=137_9083_7051;//手机号码console.log(num1);//13790837050让num2=1_000_000_000;//大数字console.log(num2);//1000000000letnum3=1.000_000_000_1;//多位小数console.日志(num3);//1.0000000001restparameter(...)rest参数(形式为...变量名),用于接收函数的冗余参数,以数组的形式存储冗余参数。函数fn(val,...vals){console.log(val,vals);}fn(1,2,3,4,5);//1[2,3,4,5]it'sbetter而不是arguments参数,arguments参数的不透明和隐蔽性以及它以伪数组的形式存在给人们带来了更多的麻烦;当然,更重要的是它可以为箭头函数服务,我们知道箭头函数内部没有所谓的this,也不会有arguments参数。它不仅可以用在函数参数上,还可以和解构赋值一起玩:var[a,...rest]=[1,2,3,4];控制台日志(一);//1console.log(rest);//[2,3,4]rest参数使用注意事项:rest参数只能放在所有参数的最后一位,否则会报错。其余参数不计入函数的长度属性。(function(a){}).length//1(function(...a){}).length//0(function(a,...b){}).length//1个展开运算符(...)spreadoperator也是个好东西,但是需要注意的是它和rest参数不是一回事,所以不要搞混了。console.log(...[1,2,3]);//123console.log({...{a:1,b:2,c:3}});//{a:1,b:2,c:3}console.log([...document.querySelectorAll('div')]);//[div,div,div]console.log(...newSet([1,2,3]));//123console.log(...newMap([['name','Orange'],['age',18]]));//["name","Orange"]["age",18]扩展运算符比较容易理解和使用,可读性也很好,但即便如此,也经不起怪高手的操作,很容易就写出令人费解的写法。console.log({...['Orange','Someone','Person']});//{0:"Orange",1:"Someone",2:"Person"}console.log({...'orangesomeone'});//{0:"orange",1:"someone",2:"person"}functionfn(...[a,b,c]){console.log(a,b,c);}fn(1,2,3);//1,2,3fn(1,2,3,4);//1,2,3在这里只是展开运算符,不就是Rest参数吗ohexponentoperator(**)exponentoperator(**)这个东西和Math.pow()是一样的,只是写法变得简洁。控制台日志(2**2);//2*2=4console.log(2**3);//2*2*2=8等价于console.log(Math.pow(2,2));//4console.log(Math.pow(2,3));//3但要小心,这个人从右边数起:console.log(2**3**2);//2**(3*3)=2**9=2*2...=512链式判断运算符(.?)不知道大家有没有写过这样的语句:varresponse={}console.log(响应&&response.data&&response.data.name);//undefined为了不让读取对象内部某个属性时控制台报错,我们往往需要判断该属性的上层对象是否存在,所以这样写是没有问题的,但是一旦读取的属性数量多,写起来会很麻烦。这次来了,ES2020带着链式判断算子来到我们面前。console.log(响应?.data?.name);//undefined是不是很简洁,真的牛逼,有没有(-^〇^-)?链式判断运算符的原理是判断左边的对象是null还是undefined。如果是,则不会进行进一步的计算,但会返回undefined。空值判断运算符(??)有时候我们需要判断一个变量是否为空,如果为空则设置默认值,否则为原值。那我们大概怎么写://varvalue='';//varvalue=0;//varvalue=undefined;//varvalue=null;console.log(value?value:'valueisanullvalue');//''和0也会被算为空将返回右侧,否则返回左侧的值console.log(value??'valuehasnovalue');globalThisJavaScript可以运行在不同的环境中,如浏览器、Worker、Node等,虽然都是JS,语法基本一样,只是全局对象不同,浏览器全局对象是window,WebWorker全局对象是self,Node全局对象是global,针对这种情况,为了使用一个统一不同环境下的全局对象,ES2020标准引入了globalThis。//browserconsole.log(globalThis);//=>Window{...}//nodeconsole.log(globalThis);//=>Object[global]{...}//webworkerconsole.log(globalThis);//=>DedicatedWorkerGlobalScope{...}TS了解了JS中的各种符号后,th接下来就是TS中的一些符号,不过TS中奇怪的符号并不多,大部分都是和JS一样或者进化而来的,下面我们继续观察观察。(为了展示报错的效果,下面的代码基本都会用截图代替,代码不要用,都是很简单的代码,目的是解释每个符号的作用和含义。)非空断言操作符(!)先来介绍第一个符号非空断言操作符,但是为了展示这个符号的功能,我们还需要对tsconfig.json做一些修改,这个文件是的配置文件TS,一般TS工程的根目录下都可以找到,也可以通过npxtsc--init命令主动生成。那么我们需要打开文件的“strictNullChecks”:true配置项,这是为什么呢?主要原因是null和undefined是TS中的基本类型,分别有null和undefined的值。默认情况下,它们是所有类型的子类型,即它们可以分配给任何类型;当我们打开这个选项时,它们不能随意赋值给其他类型,只能赋值给自己的类型。配置项打开前:配置项打开后:如上图,nickname可能未定义,不能直接赋值给realname,否则会报错。但是如果经过一些操作,昵称已经确定是有值的,比如:我们怎么告诉TS呢?让它不报错?这时候可以使用非空断言操作符。这样一来,应该是比较简单易懂的。..Optionalattribute(?:)Optionalattribute这个可以说是接口(interface)的一个属性,一个非常灵活的接口概念,我们通常可以用它来限制一个对象,例如:一个人机界面定义在figure,分别有name,age,hobbies,可以用来限定对象,但是有时候,有些对象是没有爱好的(嗯,没有爱好的人太惨了︶︿︶)这个item会像图片和小明一样,只能报错,怎么办?这时候可以使用接口的可选属性,比如:链式判断运算符(.?)这个运算符在JS版本中和可选链式运算符的作用是一样的,但实际上是TS版本的实现.也是判断左边的对象是null还是undefined。如果是,则不再继续计算,而是返回undefinedvarobj:any=undefined;if(obj?.name){}//相当于if(obj&&obj.name){}写这个的目的是以防止控制台报错,因为obj类型可能不确定。空值判断运算符(??)该运算符与JS版本中的空值判断运算符作用相同,只是TS版本的实现。同样,只有当运算符左边的值为null或undefined时,才返回右边的值,否则返回左边的值。变量值:字符串|未定义|null='';console.log(value??'valueisanullvalue');//当值为null时,取默认值跨类型运算符(&)与运算符and(&&)类似,但作用于一个类型定义,它只有一个符号(&)。使用交集类型运算符,可以将多个类型叠加形成一个新类型,这个新类型将包含该类型所需的所有特征,没有一个可以省略。它也可以用在接口上:这没什么好说的。当然在使用的时候也有需要注意的地方,比如:当两种类型的cross属性相同,但是属性类型定义不同的时候,结果类型变为never类型。这是因为string&number类型显然不存在,所以变成了never类型。联合型分隔符(|)也很简单,它类似于或(||),同样只有一个符号(|),所以不要搞错。这些例子都很简单,就不多说了。但是很多时候在使用union类型分隔符的时候,会遇到一类问题,比如:图中我们读到的name或者age在TS中是不允许的,TS无法判断obj上是否存在这两个属性;有很多方法可以解决这类问题。我们将这些方式统称为“类型保护”。其实简单理解就是先判断图中obj对象的类型,再进行后续操作。(这里顺便提一下“类型保护”,更多内容大家可以自行查阅相关资料,这里就不赘述了)类型断言类型断言有点像类型转换,但是也不是嘛,毕竟没有转换,只是“忽悠”了TS类型检查而已。它有两种写法,我们分别来看一下。TS不允许我们将未知类型或其他类型分配给明确类型的变量,但有时我们必须这样做。像图中的情况要怎么做呢?assyntax<>语法好理解吗?装饰器(@xxx)什么是装饰器?记住吧,本质就是调用一个函数,只是一个语法糖,没什么大不了的。它的作用是允许在不改变其结构的情况下向现有对象添加新功能。要使用它,还是要在tsconfig.json中打开它的相关配置项,只需要开启"experimentalDecorators":true和"emitDecoratorMetadata":true即可。话不多说,我们写个小例子观察一下:);}}varp=newPerson();这是执行后打印在控制台上的结果:呃……是不是很有趣?学过Java的朋友可能不会陌生。这同Java的装饰器模式是相似的。..(⊙o⊙)装饰器也可以传递参数,并且是顺序执行的:functionclassFn(target:any){console.log('classdecorator:',target);返回函数(参数:任何){控制台。log('自定义类装饰器参数:',params)}}@classFn('橙子-1')@classFn('小明同学-2')classPerson{constructor(){console.log('实例转换');}}varp=newPerson();装饰器不仅仅是类装饰器,它们分为:类装饰器、属性装饰器、方法装饰器、参数装饰器(Parameterdecorators)em……这个东西好像涉及的内容很多,就不介绍了他们在这里一个接一个。我不想用太多的内容让你厌烦。本章的目的是带大家认识各种符号,以免在接手项目时完全瞎了眼,大致了解语法即可。(哈哈哈,终于水过了。。。逃了,大家开心)至此,这篇文章就写完了,来撒花吧。我希望这篇文章对你有所帮助。如有任何疑问,期待您的留言。照例,点赞+评论=你懂,收藏=你精通。原文首发于掘金,欢迎踩坑。
