我们用实际题目来看看这些标点符号到底有多少我们平时忽略的陷阱
逗号
我们对逗号的常见用法是,当我们连续声明一些变量时,我们可以有更多的var
var a=1,b=2,c=3;
方法参数之间用冒号分隔,对象属性也用冒号分隔
function fbn(name,title){}
var person={
name:"Byron",
age:"24"
};
但是我们也会遇到这样的问题,形参表达式中出现的冒号
var a=(1,2,3);//3
该表达式的计算结果为最后一个子表达式的结果,即 3。并且每个子表达式都会被执行,但“返回值”是最后一个表达式的结果,如上面的代码所示
var a,b;
a=(b=1,2);
console.log(a);//2
console.log(b);//1
逗号
?: 操作员
var p=gender ? 'male':female;
对象字面量
var obj={
name:"Byron",
age:24
};
切换造句
switch(t){
case 1:
console.log('xxx');
break;
case 2:
console.log('ooo');
break;
}
相信前面的用法大家已经很熟悉了,那么我们就可以进入正题了
x:y:z:1,2,3;
计算时会不会有错误? 不报错的运行结果是什么呢?很多朋友第一次听到这个都会很惊讶,以为肯定有错误,但是结果却是3,我们来看看为什么
虽然引号也有一个作用:声明标签,但 JavaScript 中的句子可以有标签前缀,我们称之为标签句,break 或 continue 可以与标签句结合使用来控制流程。 如果有重复的标签,就会出现错误。我们里面的句子可以这样翻译
x:
y:
z:1,2,3
这样结合我们昨天讲的冒号的知识就可以理解为什么结果是3了。 很多优化建议并不提倡使用标签。 你是否想到了C语言中的goto,它使用标签来控制流程,使得程序相当难以理解。
var x=1;
foo:{
x=2;
break foo;
x=3;
}
console.log(x);//2
牙套
函数字面量声明形式:整句是形参语句,左值部分包含十个表达式,直接量构造一个对象
var obj={
name:"Byron",
age:24
};
大括号不带来块作用域
熟悉JavaScript的朋友一定已经熟悉这一点了。 大括号实际上是否可以组织复杂的句子等等,指的是同一个“块”,但不幸的是JavaScript只有函数作用域而没有块作用域。 下面的方法会声明全局变量,这个小知识点常常让英雄跪拜
在函数外部使用声明的变量(无论是否使用var)
不要在函数中使用 var 声明变量
将形式参数直接传递给窗口属性
var a=2;
function fn(){
b=3;
window.c=4;
}
不仅是这三个,其余的都是函数作用域内的局部变量,这在很多 JavaScript 规范中都提到过,并且变量的声明应该尽可能延迟,因为没有块作用域
function fn(n){
if(n>1){
var a=n;
}else{
var b=n;
}
console.log(a);
}
这种代码在很多语言中都存在句子错误。 因为if和else的大括号具有块作用域,所以变量a和b都在其对应的块作用域内,在块外无法访问它们。 但在 JavaScript 中javascript 冒号,没有块作用域,因此 if 和 else 中声明的变量 console.log 仍然可以访问。 这确实是一个糟糕的设计。 为了减少出错的可能性,尽量尽早声明变量。
许多面试问题都是基于这些知识
{a:1};
var x={a:1};
{a:1,b:2};
var y={a:1,b:2};
自己尝试一下,觉得很惊奇,我们来分析一下
{a:1}JavaScript有传说中的“句子优先”,即当大括号既可以理解为复合句块又可以理解为对象字面量时,JavaScript就会将其理解为复合句。 虽然{a:1}是a:1,但是想想引号的作用,你知道为什么返回值是1吗?
varx={a:1} 当{a:1}作为左值出现时,显然它不是一个句子,而是一个直接定量表达式,因此大括号被当成一个宾语直接定量句子,结果是一个对象。
{a:1,b:2}; 前面的读起来很容易,可以翻译为:a:1,b:2加上冒号和逗号,结果很明显,是2。但是虽然报错了,但是这是为什么呢? 冒号运算符之前必须有一个表达式,而标签句本质上是一个labelstatement,是一个句子,所以会报错。
了解了这些知识后,我们再尝试几个问题(看控制台上的答案javascript 冒号,不要试图alert)
{foo:[1,2,3]}[0];
{a:1}+2;
2+{a:1};
不知道男同伴们做对了没有。 这些问题的核心都是一样的。 尽管大括号看起来没有任何作用,但它们可以充当句子分隔符。 {foo:[1,2,3]}[0]可以理解为
{foo:[1,2,3]};
[0];
所以返回值为[0],{a:1}+2变为
{a:1};
+2
然而! 为什么 2+{a:1} 不同? 此时是乘法运算符引起的,减号左结合,{}被解析为表达式(一定是表达式的减法),根据知识对象{a:1转换为NaN } 在数据类型中