众所周知JavaScript是一个基于对象的语言,大家不要忘记另外一个层面,它是一门“函数式编程”语言。对的就是函数。很多从后台转过来的程序员(Java,C#等)对JS可谓深恶痛绝,我曾经就是其中一员。应为大家总想尝试像使用自己更熟悉的另一种语言一样来使用JS,然后发现JS并不像他们熟悉的那种语言。那是应为大家不了解JS函数的独特之处。
-
函数是第一类型对象
-
它门可以通过字面量进行创建
-
它们可以赋值给变量,数组货其他对象的属性
-
它们可以作为参数传递给其他函数
-
它们可以作为函数的返回值进行返回
-
它们可以拥有动态创建并赋值的属性
JavaScript中,函数拥有全部这些功能,也就是说可以像这门语言的其他对象一样使用。因此,我们说函数是第一型(first-class)对象。(此段文字摘抄于《JavaScript Ninja》第3.1章)
好了,言归正传,回到我们今天的主题。
第一个问题,JavaScript的作用域。对于前端开发者来说再熟悉不过,JS只为我们划分了 函数作用域 和 全局作用域。换句话说只要不是在函数中定义的就是全局作用域。下面我们来看一个例子
1 if(false){ 2 var a = 5; 3 }else{ 4 var b = 8; 5 } 6 function fn(){ 7 var c = 10; 8 console.log(c); 9 } 10 console.log(a); //undefined 11 console.log(b); //8 12 fn(); //10 13 console.log(c); // Err : c is not defined
相信大家已经发现了这个问题。当if条件不满足时,JS引擎还是为我们申明了变量a。这里是引擎的预处理查找到关键字var将申明提升到了作用域顶部。由于if条件不满足导致赋值部分没有执行。这也证明了在JS中并没有"局部变量"这个说法,但是你可能会想说,es6不是有let吗?那么let在桌面端浏览器上是存在兼容问题的。所以也不适合在浏览器端使用。由于JS的函数具备 Immediately-Invoked Function Expression (IIFE) 特点。我发现了一个可以解决if...else局部变量的方法。
如果你不知道什么IIFE那么请先去了解立即执行函数后再来阅读本文。
首先请使用三目运算符(条件运算符)来代替你的if...else...
1 if(5>3){ 2 // do something 3 }else{ 4 // do something 5 } 6 /*将以上代码修改为*/ 7 8 (5>3)?(function(){ 9 //true 10 //do something 11 })():(function(){ 12 //false 13 //do something 14 })();
三目运算符后的两个表达式使用了IIFE的方式来处理,代替了if...else...的代码块,并且function封闭了作用域,还可以传参。是不是看起来非常棒呢?加上返回值还可以配合赋值操作。
随手写了一个小案例,无关事件,性能等问题。单纯探讨三目运算符。