JavaScript Core -- 不可小视的标点符号

本文深入探讨了JavaScript中常被忽视的标点符号,如逗号、冒号和大括号的实际用途及其带来的意外行为。通过实例展示了这些标点如何影响代码逻辑,包括表达式的求值、对象声明和标签语句的使用。

我们通过实际题目来看看那些平时被我们忽略掉的标点符号,到底有多少坑

逗号

逗号我们常见的用法就是在连续声明一些变量的时候,可以少些很多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语句

switch(t){
	case 1:
		console.log('xxx');
		break;
	case 2:
		console.log('ooo');
		break;
}

相信上面是大家所熟知的用法,那么我们可以来个题目

x:y:z:1,2,3;

上面运算会不会报错?不报错运算结果是什么?很多同学初次看到这个会很惊讶,觉得肯定会出错,但结果却是3,来看看为什么

其实冒号还有个作用:声明label,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只有函数作用域,没有块作用域,再JavaScript中下面做法会声明全局变量,这个小小的知识点往往引英雄竞折腰

  1. 在function外使用声明变量(无论是否使用var)
  2. 在function内不使用var 声明变量
  3. 直接赋值于window属性
var a=2;
function fn(){
	b=3;
	window.c=4;
}

除了这三种剩下的就是function范围内的局部变量了,在很多JavaScript规范中都有提到,尽量提早声明变量正是由于其没有块作用域

function fn(n){
	if(n>1){
		var a=n;
	}else{
		var b=n;
	}
	console.log(a);
}

这样的代码在很多语言中有语法错误,因为if和else的大括号有块作用域,变量a、b在自己对应块作用域中,出了块就访问不到了。但在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了。

var x={a:1} 当{a:1} 作为右值出现的时候,明显就不是语句,而是直接量表达式了,所以把大括号当作对象直接量语法处理,结果是个对象。

{a:1,b:2}; 看了上面这个就简单了,可以翻译为:a:1,b:2 结合逗号和冒号作用,结果似乎显而易见了,就是2嘛。然而其实报错了,这是为什么?在逗号运算符后面必须是表达式,而标签语句本质为label statement,是条语句,所以就报错了。

了解了这些知识我们再来试几个题目(看答案在控制台上,不要试图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


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值