💜《JavaScript 语言精粹》附录之毒瘤篇

118 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

那会在一言一行中证明其可怕。 ——— 威廉 · 莎士比亚,《泰尔亲王佩里克里斯》(Pericles, Prince of Tyre)

全局变量

  • 在 JavaScript 所有的糟糕特性之中,最为糟糕的一个就是它对全局变量的依赖。
  • JavaScript 没有链接器(linker),所有的编译单元都载入一个公共全局对象中。

共有 3 种方式定义全局变量。

  • 第一种是在任何函数之外放置一个 var 语句:

    var foo = value;
    
  • 第二种是直接给全局对象添加一个属性。全局对象是所有全局变量的容器。在 Web 浏览器里,全局对象名为 window

    window.foo = value;
    
  • 第三种是直接使用未经声明的变量,这被称为隐式的全局变量:

    foo = value
    

忘记声明变量成了一个非常普遍的错误。JavaScript 的策略是让那些忘记预先声明的变量成为全局变量。

作用域

  • JavaScript 的语法源于 C。
  • 在所有其他类似 C 语音风格的语言里,一个代码块(括在一对花括号中的一组语句)会创造一个作用域。
  • 代码块中声明的变量在其外部是不可见的。

自动插入分号

JavaScript 有一个自动修复机制,它试图通过自动插入分号来修正有缺损的程序。但是,千万不要指望它,它可能会掩盖更为严重的错误。

保留字

  • 它们不能被用来命名变量或参数。
  • 当保留字被用做对象字面量的键值时,它们必须被引号括起来
var method;  // ok
var class; // false
object = { box: value}; // ok
object = { case: value}; // false
object = { 'case': value}; // ok
object.box = value; // ok
object.case = value; // fasle
object['case'] = value // ok

Unicode

Unicode 把一对字符视为一个单一的字符。而 JavaScript 认为一对字符是两个不同的字符。

typeof

typeof 运算符返回一个用于识别其运算数类型的字符串。

typeof null // is object, not null

my_value === null
if(my_value && typeof my_value === 'object') {
	// my_value 是一个对象或数组
}

parseInt

parseInt 是一个把字符串转换为整数的函数。

parseInt 可以接受一个基数作为参数,如此一来 parseInt(”08”, 10) 结果为 8。

+

  • + 运算符可以用于加法运算或字符串连接
  • 如果其中一个运算数是空字符串,它会把另一个运算数转换成字符串并返回。
  • 如果两个运算数都是数字,它返回两者之和。
  • 否则,它把两个运算数都转换为字符串并连接起来。

NaN

  • NaN是一个特殊的数量值。
  • 它表示的不是一个数字
  • typeof 不能辨别数字和 NaN,而且 NaN 也不等于它自己
NaN === NaN // false
NaN !== NaN // true

JavaScript 提供了一个 isNaN 函数,可以辨别数字与NaN:

isNaN(NaN)   // true
isNaN(0)     // false
isNaN('oops')// true
isNaN('0')   // false

判断一个值是否可用做数字的最佳方法是使用 isFinite 函数,因为它会筛除掉 NaNInfinity。遗憾的是,isFinite 会试图把它的运算数转换为一个数字,所以,如果值事实上不是一个数字,它就不是一个好的测试。你可以这样定义自己的 isNumebr 函数:

var isNumber = function isNumber(value) {
	return typeof value === 'Number' && isFinite(value);
}

伪数组

JavaScript 没有真正的数组。

typeof 运算符不能辨别数组和对象。要判断一个值是否为数组,你还需要检查它的 constructor 属性:

if(my_value && typeof my_value === 'object' && my_value.constructor === Array) {
	// my_value 是一个数组;
}

arguments 数组不是一个数组,它只是一个有着 length 成员属性的对象。上面的检测会分辨出 arguments 并不是一个数组。

假值

JavaScript 的众多假值:

类型
0Number
NaN(非数字)Number
‘ ‘(空字符串)String
falseBoolean
nullObject
undefinedUndefined

这些值全部都等同于假,但它们是不可互换的。

undefinedNaN 并不是常量。

hasOwnProperty

hasOwnProperty 方法是一个方法,而不是一个运算符,所以在任何对象中,它可能会被一个不同的函数甚至一个非函数的值所替换

对象

JavaScript 的对象永远不会是真的空对象,因为它们可以从原型链中取得成员属性。

对象继承自 Object.prototype,而 Object.prototype 包含着一个名为 constructor 的成员对象,它的值是一个 object