你可能从未使用过的11+个JavaScript特性(小结)
重要
这篇文章中描述的大多数功能已被暂停使用(甚至不推荐使用)。它们仍然在许多图书中很常见,因此值得学习。
一、逗号运算符
,是用于分隔表达式并返回链中最后一个表达式的运算符。
letoo=(1,2,3) console.log(oo)//3
这里有三个主要表达式1、2和3。所有这些表达式均被求值,最后一个赋给oo。
我们在for循环中看到这个:
for(leti=0,ii=1;i<10;i++,ii--){...}
当我们要编写短的lambda函数时,这会派上用场:
constlb=(a,b,arr)=>(arr.push(a*b),a*b)
这里有两个语句,第一个将乘法结果推入数组arr,第二个将乘数a和b推入数组。第二个结果就是返回给调用者的内容。
对于三元运算符,它也很有用,因为与短lambda语法相同,它仅接受表达式而不是语句。
二、in
in是用于检查对象中属性是否存在的关键字。我们在for..in循环中使用了它,但没有意识到,其实in也是一个关键字:)
如果对象上存在属性,则in将返回true,否则将返回false。
consto={ prop:1 } console.log("prop"ino)//true
看,in可以独立使用,而不是在for..in中。
它将检查"prop"是否可作为o对象中的属性使用。它返回true,因为我们在o中定义了"prop"属性。
如果我们检查未定义的属性:
consto={ prop:1 } console.log("prop1"ino)//false
它返回false,因为"prop1"在o中未定义。
三、Array构造函数
你知道我们可以不使用传统方法定义数组吗?
constarr=[1,2,3]
怎么样?
我们也可以使用Array:
constarr=newArray(1,2,3)
传递给Array构造函数的参数的排列将构成其索引的基础。
1是第一个参数,其索引为0;2是第二个参数,其索引为1;3是第三个参数,其索引为2。
arr[0]//1 arr[1]//2 arr[2]//3
所以,
constarr=newArray(1,2,3)
和
constarr=[1,2,3]
表达的是一个意思。
但使用newArray()有一个问题,例如:
vara=newArray(10,20); a[0]//返回10 a.length//返回2
但:
vara=newArray(10); a[0]//返回undefined a.length//返回10
当你仅给Array构造函数一个整数(大于等于0的整数,否则将会报错)时,才会发生这种情况。这是为什么喃?
其实,新的Array构造函数正在从某些编程语言中提取思想,在这些语言中,你需要为数组指定内存,这样就不会出现ArrayIndexOutOfBounds异常。
int*a=(int*)malloc(10*sizeof(int));//yaol'c int*a=newint[10];//c++ int[]a=newint[10];//java
是的,它实际上是在创建一个长度为10的数组。我们在Javascript中没有sizeof函数,但是toString足以证明这一点。
a.toString()//返回",,,,,,,,,"它相当于[,,,,,,,,,] a//[empty×10]
所以,当将一个参数传递给的newArray,将导致JS引擎为传递的参数大小的数组分配空间。
并且这也在EcmaScript规范中:
看,这不是矛盾的。规格中都有所有描述。在得出任何结论之前,我们应该始终先阅读任何语言的规范。
四、Function构造函数
你是否知道我们可以使用Function构造函数定义Function。
你不明白吧?让我更清楚。在JavaScript中,我们定义如下函数:
constmul=(a,b)=>a*b //或 functionmul(a,b){ returna*b } //或 constmul=function(a,b){ returna*b }
我们也可以这样做,来实现相同的功能:
constmul=newFunction("a","b","returna*b")
传递给Function的参数形成函数的参数和主体。变量mul成为函数名称。
并且,最后一个参数将是函数的主体,而最后一个参数之前的参数将成为函数的参数。
在在mul中。 "a"和"b"是函数将接收的参数,"returna*b"是函数的主体。它实现将"a"和"b"相乘并返回结果。
我们使用mul(…)调用该函数,并传入参数:
constmul=newFunction("a","b","returna*b") console.log(mul(7,8))//56
根据MDN:
Function 构造函数创建一个新的 Function 对象。直接调用此构造函数可用动态创建函数,但会遭遇来自 eval 的安全问题和相对较小的性能问题。然而,与eval不同的是,Function构造函数只在全局作用域中运行。
五、数组解构
我们可以通过使用元素的索引号来分解数组中的元素。
constarr=[1,2,3]
元素1、2、3的索引分别为0、1、2,即:
arr[0]//1
在日常开发中,我们最常使用的是对象解构:
leto={ prop:1 } o["prop"]//1 //解构 const{prop}=o prop//1
所以,我们将解构用于数组上:
constarr=[1,2,3] const{0:firstA,1:secA,2:thirdA}=arr firstA//1 secA//2 thirdA//3
所以我们可以使用索引号来提取元素。索引是定义数组中元素位置的属性。
constarr=[1,2,3]
相当于:
constarr={ 0:1, 1:2, 2:3, length:3 }
数组也是对象,这就是为什么要对其进行对象分解的原因,但是还有一种特殊的数组分解语法:
const[first,second,third]=arr first//1 second//2 third//3
注意:应尽可能避免知道数组中的特定位置信息(开始、结束索引是什么)。
六、使用length属性减少数组内容
数组中的length属性表示数组中元素的数目。
constarr=[1,2,3] arr.length//3
减小length属性值,会使JS引擎将数组元素个数减少到与length属性的值相等。
constarr=[1,2,3] arr.length//3 arr.length=1 arr//[1]
arr的length属性值更改为1,因此arr减少了元素个数,使其等于length属性值。
如果增加length属性,则JS引擎将添加元素(未定义的元素)以使数组中的元素数量达到length属性的值。
constarr=[1,2,3] arr.length//3 arr.length=1 arr//[1] arr.length=5 arr//[1,empty×4]
arr中的元素只有一个,然后我们将长度增加到5,因此又增加了4个元素长度,使元素数达到5。
七、Arguments
我们可以使用arguments对象获取传递给函数的参数,而无需在函数中明确定义arguments变量:
functionmyFunc(){ console.log(arguments[0])//34 console.log(arguments[1])//89 } myFunc(34,89)
arguments对象是数组索引的。也就是说,属性是数字,因此可以通过键引用进行访问。
arguments对象是从Arguments类实例化的,该类具有一些很酷的属性。
arguments.callee.name指当前正在调用的函数的名称。
functionmyFunc(){ console.log(arguments.callee.name)//myFunc } myFunc(34,89)
arguments.callee.caller.name是指调用当前执行函数的函数的名称。
functionmyFunc(){ console.log(arguments.callee.name)//myFunc console.log(arguments.callee.caller.name)//myFuncCallee } (functionmyFuncCallee(){ myFunc(34,89) })()
这在可变参数功能中特别有用。
八、跳过()
你是否知道实例化对象时可以跳过方括号()?
例如:
classD{ logger(){ console.log("D") } } //一般情况下,我们这么做: (newD()).logger();//D //其实,我们可以跳过(): (newD).logger();//D //并且它可以正常运行
即使在内置类中,括号也是可选的:
(newDate).getDay(); (newDate).getMonth(); (newDate).getYear();
九、void
void是JS中的关键字,用于评估语句并返回未定义。
例如:
classD{ logger(){ return89 } } constd=newD console.log(voidd.logger())//undefined
logger方法应该返回89,但是void关键字将使其无效并返回undefined。
我曾经读到过undefined之前可能会被赋予另一个值,而这会伪造其语义。因此,使用void运算符可确保你得到一个真正的undefined。也用于最小化目的。
十、通过__proto__继承
_proto_是从JavaScript中的对象继承属性的方法。__proto__是 Object.prototype的访问器属性,它公开访问对象的[[Prototype]]。
此__proto__将其[[Prototype]]中设置的对象的所有属性设置为目标对象。
让我们看一个例子:
constl=console.log constobj={ method:function(){ l("methodinobj") } } constobj2={} obj2.__proto__=obj obj2.method()//methodinobj
我们有两个对象常量:obj和obj2。obj具有method属性。obj2是一个空的对象常量,即它没有属性。
我们访问obj2的__proto__并将其设置为obj。这会将通过Object.prototype可访问的obj的所有属性复制到obj2。这就是为什么我们可以在obj2上调用方法而不会在没有定义的情况下得到错误的原因。
obj2继承了obj的属性,因此method方法属性将在其属性中可用。
原型可用于对象,例如对象常量、对象、数组、函数、日期、RegEx、数字、布尔值、字符串。
十一、一元运算符+
一元+运算符将其操作数转换为数字类型。
+"23"//23 +{}//NaN +null//0 +undefined//NaN +{valueOf:()=>67}//67 +"nnamdi45"//NaN
当我们希望将变量快速转换为Number时,这非常方便。
十二、一元运算符-
一元运算符-将其操作数转换为Number类型,然后取反。
该运算符将一元+运算符的结果取反。首先,它将操作数转换为其Number值,然后取反该值。
-"23"//-23
此处发生的是,字符串"23"将转换为其数字类型,从而得到23。然后,此正数将转换为其负数形式-23。
-{}//NaN -null//-0 -undefined//NaN -{valueOf:()=>67}//-67 -"nnamdi45"//NaN
如果转换为数值的结果为NaN,则不会应用取反。
取负+0产生-0,取负-0产生+0。
-+0//-0 --0//0
十三、指数运算符**
该运算符用于指定数字的指数。
在数学中,2^3^意味着将2乘以三次:
2*2*2
我们可以使用**运算符在JS中进行相同的操作:
2**3//8 9**3//729
总结
本文翻译自11+JavaScriptFeaturesYou'veProbablyNeverUsed
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。