百度贴吧的一段语法糖代码分析
function r(){var i="\u5176\u4ed6";return"1"==t.is_zone_forum&&(i="\u6838\u5fc3\u533a"),$("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus")?i="\u770b\u5e16":$("#tab_picture").parent(".j_tbnav_tab").hasClass("focus")?i="\u56fe\u7247":$(".j_tbnav_tab").eq(2).hasClass("focus")?i="1"==t.is_zone_forum?"\u56fe\u7247":"\u7cbe\u54c1":$(".j_tbnav_tab").eq(3).hasClass("focus")?i="1"==t.is_zone_forum?"\u7cbe\u54c1":"\u7fa4\u7ec4":$(".j_tbnav_tab").eq(4).hasClass("focus")&&(i="\u7fa4\u7ec4"),i}
Unicode转中文,Tab对齐
1 function r() { 2 var i = "其他"; 3 return "1" == t.is_zone_forum && (i = "核心区") 4 ,$("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus") 5 ? i = "看帖" 6 : $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus") 7 ? i = "图片" 8 : $(".j_tbnav_tab").eq(2).hasClass("focus") 9 ? i = "1" == t.is_zone_forum 10 ? "图片" 11 : "精品" 12 : $(".j_tbnav_tab").eq(3).hasClass("focus") 13 ? i = "1" == t.is_zone_forum 14 ? "精品" 15 : "群组" 16 : $(".j_tbnav_tab").eq(4).hasClass("focus") && (i = "群组") 17 ,i 18 }
下面分析这段代码:
首先定义了字符串 i,初始值="其他"
var i = "其他";
然后return 逗号表达式 ,可以将上方代码概括为return 【表达式1,表达式2,表达式3】
(仔细看,第4行最前面有逗号,第17行最前面有逗号)
表达式1
"1" == t.is_zone_forum && (i = "核心区")
表达式2
$("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus") ? i = "看帖" : $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus") ? i = "图片" : $(".j_tbnav_tab").eq(2).hasClass("focus") ? i = "1" == t.is_zone_forum ? "图片" : "精品" : $(".j_tbnav_tab").eq(3).hasClass("focus") ? i = "1" == t.is_zone_forum ? "精品" : "群组" : $(".j_tbnav_tab").eq(4).hasClass("focus") && (i = "群组")
表达式3
i
逗号表达式的运算规则:【逗号表达式从左往右运算,整个逗号表达式的值是最后一个表达式的值】
逗号表达式中的最后一个表达式是表达式3,也就是 i,所以 return 逗号表达式 其实是
return i
下面分析表达式1
"1" == t.is_zone_forum && (i = "核心区")
表达式1用到了逻辑运算符的短路运算
此处是逻辑与&&,可概括为 【表达式a && 表达式b】
逻辑与&& 两边的表达式,同真才为真,有假即为假
也就是说,只要表达式a为假,那么整个逻辑表达式肯定为假,不必运算表达式b【表达式b被"短路"】
只有表达式a为真时,才会运算表达式b
表达式1没有赋值给其他变量,实际上就是隐晦的if语句("1"放在左边是为了防止 相等==写成赋值=)
if("1" == t.is_zone_forum) { i = "核心区" }
下面分析表达式2
1 $("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus") 2 ? i = "看帖" 3 : $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus") 4 ? i = "图片" 5 : $(".j_tbnav_tab").eq(2).hasClass("focus") 6 ? i = "1" == t.is_zone_forum 7 ? "图片" 8 : "精品" 9 : $(".j_tbnav_tab").eq(3).hasClass("focus") 10 ? i = "1" == t.is_zone_forum 11 ? "精品" 12 : "群组" 13 : $(".j_tbnav_tab").eq(4).hasClass("focus") && (i = "群组")
表达式2用到了条件运算符 ?:(唯一的三目运算符/三元运算符)
条件运算符有一个冒号和一个问号,可概括为 【逻辑表达式 ? 表达式a : 表达式b】 (左式整体可称为条件表达式)
条件表达式与if else类似,如果其中的逻辑表达式为真,执行表达式a;逻辑表达式为假,执行表达式b
只不过条件表达式本身还有值,其中哪个表达式执行,条件表达式整体的值就等于那个式的值
如果条件表达式没有赋值给变量,可以直接改写为if else
if( 逻辑表达式 ) { 表达式a } else { 表达式b }
如果条件表达式赋值给变量,即 变量 = 逻辑表达式 ? 表达式a : 表达式b ,则改写为if else并在其中赋值
if( 逻辑表达式 ) { 变量 = 表达式a } else { 变量 = 表达式b }
举个例子:
求两数最大值
max=(a>b)?a:b //条件表达式整体赋值给max
等价于
if(a>b) { max=a //条件表达式的值就是变量a的值 } else { max=b //条件表达式的值就是变量b的值 }
先分析表达式2的前两行
$("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus")
? i = "看帖"
改为if语句
if( $("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus") ) { i = "看帖" }
分析3,4行。第3行是else语句,后面又嵌套条件运算符
: $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus")
? i = "图片"
改为else if
else if( $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus") ) { i = "图片" }
先分析第5行。第5行是else语句,后面又嵌套条件运算符
: $(".j_tbnav_tab").eq(2).hasClass("focus")
改为else if
else if( $(".j_tbnav_tab").eq(2).hasClass("focus") )
{
再分析6,7,8行。因为两个问号挨在一起,所以合并分析
因为赋值运算符优先级低于相等关系运算符,所以先判断相等关系,再执行条件表达式,最后条件表达式整体赋值给变量 i
? i = "1" == t.is_zone_forum ? "图片" : "精品"
与第5行的分析合并
else if( $(".j_tbnav_tab").eq(2).hasClass("focus") ) { if( "1" == t.is_zone_forum ) { i="图片" } else { i="精品" } }
先分析第9行。第9行是else语句,后面又嵌套条件运算符
: $(".j_tbnav_tab").eq(3).hasClass("focus")
改为else if
else if( $(".j_tbnav_tab").eq(3).hasClass("focus") ) {
再分析10,11,12行。因为两个问号挨在一起,所以合并分析
因为赋值运算符优先级低于相等关系运算符,所以先判断相等关系,再执行条件表达式,最后条件表达式整体赋值给变量 i
? i = "1" == t.is_zone_forum ? "精品" : "群组"
与第9行的分析合并
else if( $(".j_tbnav_tab").eq(3).hasClass("focus") ) { if( "1" == t.is_zone_forum ) { i="精品" } else { i="群组" } }
最后分析第13行,第13行是else语句,后面又有逻辑与&&运算符的短路运算
: $(".j_tbnav_tab").eq(4).hasClass("focus") && (i = "群组")
改为else if
else if( $(".j_tbnav_tab").eq(4).hasClass("focus") ) { i = "群组" }
表达式2改为
if( $("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus") ) { i = "看帖" } else if( $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus") ) { i = "图片" } else if( $(".j_tbnav_tab").eq(2).hasClass("focus") ) { if( "1" == t.is_zone_forum ) { i="图片" } else { i="精品" } } else if( $(".j_tbnav_tab").eq(3).hasClass("focus") ) { if( "1" == t.is_zone_forum ) { i="精品" } else { i="群组" } } else if( $(".j_tbnav_tab").eq(4).hasClass("focus") ) { i = "群组" }
最终,原代码和等价代码对比
function r() { var i = "其他"; return "1" == t.is_zone_forum && (i = "核心区") ,$("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus") ? i = "看帖" : $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus") ? i = "图片" : $(".j_tbnav_tab").eq(2).hasClass("focus") ? i = "1" == t.is_zone_forum ? "图片" : "精品" : $(".j_tbnav_tab").eq(3).hasClass("focus") ? i = "1" == t.is_zone_forum ? "精品" : "群组" : $(".j_tbnav_tab").eq(4).hasClass("focus") && (i = "群组") ,i }
function r() { var i = "其他"; if( "1" == t.is_zone_forum ) { i = "核心区" } if( $("#tab_forumname").parent(".j_tbnav_tab").hasClass("focus") ) { i = "看帖" } else if( $("#tab_picture").parent(".j_tbnav_tab").hasClass("focus") ) { i = "图片" } else if( $(".j_tbnav_tab").eq(2).hasClass("focus") ) { if( "1" == t.is_zone_forum ) { i="图片" } else { i="精品" } } else if( $(".j_tbnav_tab").eq(3).hasClass("focus") ) { if( "1" == t.is_zone_forum ) { i="精品" } else { i="群组" } } else if( $(".j_tbnav_tab").eq(4).hasClass("focus") ) { i = "群组" } return i }