【JS系列】盘点那些惹是生非的语法

627 阅读3分钟

前言

  很多朋友在学习之初都感受到了JS的灵活强大,但是也发现了一些蹩脚的语法,在使用时我们如履薄冰

  之前我的想法是把它们牢记,以便使用时知道如何避坑,并且它们还可能会在面试中被问到

  这两天翻看了《JavaScript语言精粹》这本书,让我换了一种思路——既然是蹩脚的语法,那就尽量避开它们

  本文将选取一些常见的坑坑语法进行讨论

1. 全局变量

  当一个程序变得庞大时,全局变量将变得难以维护,因为所有作用域都可以改变它们,因此容易造成全局污染

  创建全局变量的方式有三种:

  • 在函数外使用var创建变量
  • 添加属性到window对象,如 window.key = value
  • 不使用var创建变量(隐式全局变量),如 a = 1

  如何将全局变量的影响最小化?

  • 只定义一个全局变量,将其他变量都归于其下
var App = {}

App.person = {
  name: "一灯",
  age: 23
}

App.car = {
  color: "red",
  name: "桑塔拉"
}
  • 通过闭包

2. 块作用域

  ES6之前只有var关键字定义变量,是没有块级作用域的。ES6出现后诞生了let和const解救了这个问题

3. 自动插入分号机制

  JavaScript会自动插入分号修正缺损的代码,但有时候会出现意外的“惊喜”

return
{
  name: "一灯"
}

//以上代码本意是要返回一个对象,然而JS处理过后是这样:
//直接结束,没有返回对象
return;
{
  name: "一灯"
};

//因此使用return时,不要单独一行写return
return {
  name: "一灯"
}

4. 保留字问题

  保留字不能用来命令变量、参数,但可用来命名对象的键值,只是必须用引号括起来,并且不可用“点表示法”访问,而可用“[]表示法”访问

var object = {
  class: "AAA",   //非法,但在火狐下又是合法
  'class': "AAA"  //合法
}

object.class = "BBB"      //非法
object['class'] = "BBB"   //合法

  这是什么玩意儿,咱不用了不用了好不!

5. typeof

  typeof是用于检测变量类型的运算符,然而它的作用非常有限

  typeof能准确检测的类型如下:

  • string
  • number
  • boolean
  • function

  这里推荐一种类型检测比较全面的方法:

Object.prototype.toString.call('') ;  // [object String]
Object.prototype.toString.call(88) ;   // [object Number]
Object.prototype.toString.call(true) ;// [object Boolean]
Object.prototype.toString.call(Symbol());//[object Symbol]
Object.prototype.toString.call(undefined) ;// [object Undefined]
Object.prototype.toString.call(null) ;// [object Null]
Object.prototype.toString.call(new Function()) ;// [object Function]
Object.prototype.toString.call(new Date()) ;// [object Date]
Object.prototype.toString.call([]) ;// [object Array]
Object.prototype.toString.call(new RegExp()) ;// [object RegExp]
Object.prototype.toString.call(new Error()) ;// [object Error]
Object.prototype.toString.call(document) ;// [object HTMLDocument]
Object.prototype.toString.call(window) ;//[object global]

6. +

   + 不仅是加号,也是连接符。除非两边的运算数都是数字,否则会当作连接符,结果变成字符串

  因此做加法运算一定确保两边的是数字类型,尤其JS是弱类型语言

  这里补充一点,其实对于减号,会更加复杂繁琐(不了不了伤身体.jpg),最好也确保两边的是数字类型

7. 浮点数

  想起了被小学数学老师看到会打死的 0.1+0.2 不等于 0.3

  我们都知道二进制浮点数无法精确运算十进制小数,因此避免直接运算小数

  先将小数放大为整数再运算(整数运算是精确的),运算完再转换为小数

8. 假值

  JS中很多值都被定义为假,然而它们相互之间是不能互换的

  • false
  • 0
  • NaN
  • 空串
  • null
  • undefined
var object = {
  name: "一灯"
}

if(object.age == null) {
  console.log("没找到此属性")
}

//上面代码中,如果age属性不存在,应该使用undefined判断
//即使使用null没有出现问题,但有些情况下会带给你意外“惊喜”

后记

  关于JS那些蹩脚的语法本文列举不全,欢迎在下方评论列出你认为值得注意反思的语法