JavaScript 引擎会通过语法规则、优先级算法以及系统机制来处理「多重含义」的代码,把「多重含义」的代码变成「确定含义」的代码,多重含义指的是在开发人员第一眼看起来不清晰、不直观的代码。
单个加号「+」作为运算符在 JavaScript 中有三种作用:
var str = \\\'hello\\\' + \\\'world\\\';
var n = 100;
var n2 = n + 1;
在这三种表示中,字符串连接和数字求和是非常容易理解出多重含义的,因为 JavaScript 对于这两种运算的处理会依赖于数据类型检测
所以它是无法知道真实的含义是在求和还是在做字符串连接。
在计算机规则里:如果表达式中存在字符串,则优先按字符串连接进行运算。
由于加号进行的是值运算,当参与运算时会调用方法 x.valueOf() 来确定操作数的类型,如果它的类型不符合要求,则会调用 x.toString() 再次尝试,这样复杂的类型转换逻辑,实际运算的结果会变得非常难以预测 …
不过这也是 JavaScript 在动态语言方面的特性,也就是所谓的动态绑定。
最常见的形式就是作为函数声明里面的参数列表,通过括号传入参数。
而 new 关键字用于创建一个对象实例,并用括号来调用该构造器函数。
var myArray = new Array(\\\'abc\\\',1)
它也可以在 with、for、if、while、do…while 等语句里面来作为限定元素,当 if、while、do…while 这几个语句时,括号”()“会将表达式结果转换成布尔值。
括号“()”还可以用于强制表达式运算,就是我们通常说的强制运算符优先级。
函数调用过程中括号“()”是运算符,当括号()作为运算符的时候,它只作用于表达式运算而不可能作用于语句。
function foo(){
return (1+2);
}
//声明对象字面量成员
var obj = {
value: 100,
foo: function(){}
}
//标签声明
myLabel: {}
switch (obj){
case X:
break;
}
它还有一个运算符的含义,在“?:”三元表达式中表示条件为 false 的表达式分支
X ? \\\'yes\\\' : \\\'no\\\'
在所有的场景中,它都是作为语法/词法符号来使用的。
myLabel: {
//...
}
if(){
//...
}else{
//...
}
var obj = {
x: 1,
y: 2,
z: 3
}
var obj = {
x: 1,
y: 2,
z: 3
}
try {
//...
} catch (exception){
//...
} finally {
//...
}
var abc = \\\'hello\\\'
var code = `${abc}, world!`
模板被声明为字面量,在引擎正式执行代码之前完成解析,在 JavaScript 中的语法中 ${…} 用来表示一个表达式。
从语法设计的角度上来讲,解构赋值表达式「左侧运算数」是一个引用,而右侧是一个值。
将「右侧结果」复制给「左侧的引用来存储,如果左侧被引用对象没有存储能力,抛出异常。
在执行期,JavaScript 引擎将左侧的赋值模板视为一个内部结构,该结构表达了一组名字与它们的值之间的处理关系。
逗号,既可以是语法,又可以是运算符。在它作为连续运算符使用的时候,其效果表达式并返回结果值
该表达式是三个单值表达式的连续运算,其结果是最后一个表达式,也就是数字3,如果这里没有括号来调整优先级,那么按默认优先级会先完成赋值运算,就是将变量 a 赋值为 1。
这是因为逗号,被解析成了语句 var 声明时用来分割多个变量的语法分隔符,而不是连续运算符。
var foo = [\\\'one\\\', \\\'two\\\', \\\'three\\\']
var foo_sub = foo[0]
方括号可以被理解成数组声明,或者下标存取,还可以被理解成对象成员的存取。
这篇文章不是为了炫技能,在计算机系统里会存在多重含义的代码块,需要我们仔细分辨出来,如果某些细节没有理解,那在代码也许会得到有趣的结果。
题图生成于:Stable Diffusion
内容来源于《JavaScript 语言精髓与编程实战》
原创文章,作者:小道研究,如若转载,请注明出处:https://www.sudun.com/ask/34589.html