深入理解JavaScript语句与表达式的结果值
本文详细解析JavaScript中语句和表达式的结果值机制。从控制台输出的undefined入手,解释语句块、变量声明、函数声明及赋值语句的结果值规则。同时介绍ES7提案中的do表达式,探讨其获取语句块结果值的功能及当前浏览器支持现状。
JavaScript结果值的基本概念
你是否注意到,在JavaScript中,无论是单条语句还是复杂的表达式,执行后都会产生一个结果值?
在浏览器控制台调试代码时,你经常会在输出列表的末尾看到多出一个undefined,这个值正是代码执行后的结果值。
ES7的do表达式
ES7的do表达式
我们可以从ES7的一个提案开始了解:do表达式(语法为do{...},注意区别于do...while循环中的do)。
var a,b,c = 3;
a = do {
if (true) {
b = c*3;
}
};
a; //9 目前的浏览器暂不支持
do{...}表达式的作用是返回其内部语句块的结果值,这与return语句类似,但return必须包裹在函数中调用,而do表达式可以直接使用。
然而,目前主流浏览器尚未支持此功能。根据现行规范,我们不能直接获取语句块的结果值并赋值给变量(除了使用eval(),例如var a = eval('if (true) {b = c*3;}'),此时a会被赋值为eval内部语句的结果值,但强烈不建议使用eval())。
ES5规范关于结果值的规定
ES5规范关于结果值的规定
现在你应该对结果值有了基本认识。查阅ES5规范可知,JavaScript中的语句块、语句乃至表达式都会隐式返回一个结果值。总结如下:结果值是语句或表达式经过逻辑运算后的值;若无逻辑运算(即按顺序执行),则结果为最后一条子语句或表达式的结果值(语句可包含子语句)。简言之,它是语句或表达式的“隐式返回值”。JavaScript会计算每条语句并返回结果值;对于语句块,其结果值为最后一条最外层语句的结果值(忽略嵌套的子语句)。
部分浏览器会在控制台输出代码最后一条语句或语句块的结果值(本文所有代码均使用Firefox测试,不同浏览器行为可能存在差异)。
结果值可以是任何表达式的值,也可以为空(如单独的空语句;、break;、continue;)。当结果值为空时,其值为undefined。若结果值为空,浏览器会忽略该语句,并打印上一条同级的非空语句的结果值;若仅有自身一条同级语句,则打印undefined。
特例:var变量声明语句和函数声明语句的结果值均为undefined。
具体而言: 1、变量声明语句算法的返回值实际为表示该变量名称的字符串,但该值被变量声明算法屏蔽(for...in循环除外),最终返回结果为undefined。 2、对于函数声明语句,按规范解读其结果值应为该函数对象,但浏览器显示为undefined,具体原因尚不明确(可能因为函数仅定义而未执行)。 3、函数执行语句的结果值为: 3.1 若存在throw语句,则为throw语句的结果值。 3.2 若存在return语句,则为return语句的结果值。 3.3 若无throw或return语句,则结果为undefined。
示例如下:
var a,b,c = 3;
if (true) {b = c*3;} //按顺序执行到最后一条语句,输出9
; //undefined 单独的空语句
var d = 5; //undefined 所有的var声明语句的结果值均为undefined
function foo(a){
a = a+2;
return a;
}
//undefined 函数声明语句的最终结果值也为undefined
foo(1); //3 函数执行语句的结果值为函数throw、return语句的结果值,若无throw、return语句,则为undefined
if(true){a=1;}else{b=2;} //1 按逻辑计算结果执行a=1;语句
{
var a = 1,b = 2;
if(true){a;}else{b;} //输出1,最后一条空语句会被忽略
;
}
var a = 5;
switch(a){
case 1:
a+1;
break;
case 5:
a+5;
break;
case 3:
a+3;
break;
}
//10 空的break;语句会被忽略
var a = 5;
switch(a){
case 1:
a+1;
break;
case 5:
break; //执行这里,它这里无同级语句
case 3:
a+3;
break;
}
//undefined
表达式结果值的应用
接下来具体看看表达式的结果值有何用途: 大多数表达式仅有结果值而无副作用,例如:var a = 2; var b = a + 3;,其中表达式a+3的结果值为5,并被赋值给b。
而存在副作用的表达式,例如:
function foo(){
a++;
}
var a=0;
foo(); //结果值为undefined,副作用是改变了a的值
又如:
var a = 0;
var b = a++;
a; //1
b; //0
var c = a++; //结果值为undefined 副作用是c被赋值了,a变成了2
var d = a++, a; //结果值为undefined,副作用是d被赋值为2,a变成了3,实际执行的是var d = a++;
var d = (a++,a);//结果值为undefined,副作用是d被赋值为3,a变成了3,实际执行的是var d = ++a;
function foo(){
var e = f = 1; //表达式f=1的结果值为1,1又被赋值给e
}
foo();
f; //1 创建了全局变量f
e; //ReferenceError
赋值语句的副作用是将等号右侧表达式的结果值赋给左侧变量,最终整个赋值语句的结果值为该变量的值。因此我们可以这样操作:
function foo(a){
var b;
if(a&&(b = a*10;)<50){
...
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
