前言
很多朋友在学习之初都感受到了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那些蹩脚的语法本文列举不全,欢迎在下方评论列出你认为值得注意反思的语法