笔记 10 JS 类型

原文地址
参考1

类型

1 instanceof 操作符

instanceof 操作符用来比较两个操作数的构造函数
只有在比较自定义的对象时才有意义。
如果用来比较内置类型,将会和 typeof 操作符 一样用处不大。

1.1 比较自定义对象 推荐

function Foo() {}
function Bar() {}
Bar.prototype = new Foo();

new Bar() instanceof Bar; // true
new Bar() instanceof Foo; // true

// 如果仅仅设置 Bar.prototype 为函数 Foo 本身,而不是 Foo 构造函数的一个实例
Bar.prototype = Foo;
new Bar() instanceof Foo; // false

1.2 instanceof 比较内置类型 尽量不用

instanceof 用来比较属于不同 JavaScript 上下文的对象
(比如,浏览器中不同的文档结构)时将会出错,
因为它们的构造函数不会是同一个对象。

new String('foo') instanceof String; // true
new String('foo') instanceof Object; // true

'foo' instanceof String; // false
'foo' instanceof Object; // false

2 类型转换

JavaScript 是弱类型语言,
所以会在任何可能的情况下应用强制类型转换

为了避免上面复杂的强制类型转换,
强烈推荐使用严格的等于操作符。

ES5 提示: 以 0 开头的数字字面值会被作为八进制数字解析。 而在 ECMAScript 5 严格模式下,这个特性被移除了。

// 下面的比较结果是:true
new Number(10) == 10; // Number.toString() 返回的字符串被再次转换为数字

10 == '10';           // 字符串被转换为数字
10 == '+10 ';         // 同上
10 == '010';          // 同上
isNaN(null) == false; // null 被转换为数字 0
                      // 0 当然不是一个 NaN(否定之否定)

// 下面的比较结果是:false
10 == 010;
10 == '-10';

内置类型的构造函数

内置类型(比如 Number 和 String)的构造函数在被调用时,
使用或者不使用 new 的结果完全不同。


/**
 * 使用内置类型 Number 作为构造函数
 * 将会创建一个新的 Number 对象,
 * 而在不使用 new 关键字的 Number 函数
 * 更像是一个数字转换器。
 */

new Number(10) === 10;     // False, 对象与数字的比较
Number(10) === 10;         // True, 数字与数字的比较
new Number(10) + 0 === 10; // True, 由于隐式的类型转换
/**
 * 在比较中引入对象的字面值
 * 将会导致更加复杂的强制类型转换。
 * 最好的选择是把要比较的值显式的转换为
 * 三种可能的类型之一。
 */

// [1] 转换为字符串
// 将一个值加上空字符串可以轻松转换为字符串类型。
'' + 10 === '10'; // true

// [2] 转换为数字
// 使用一元的加号操作符,可以把字符串转换为数字。
+'10' === 10; // true

/**
 * 字符串转换为数字的常用方法
 */
+'010' === 10
Number('010') === 10
parseInt('010', 10) === 10  // 用来转换为整数
+'010.2' === 10.2
Number('010.2') === 10.2
parseInt('010.2', 10) === 10

// [3] 转换为布尔型
// 通过使用 否 操作符两次,可以把一个值转换为布尔型。
!!'foo';    // true
!!'0';      // true
!!'1';      // true
!!'-1'      // true
!!{};       // true
!!1         // true
!!-1        // true
!!'false'   // true
!!'true'    // true
!!undefined // false
!!null      // false
!!0         // false
!!+0        // false
!!-0        // false
!!NaN       // false
!!'';       // false
!!true;     // true 保持原样 = Boolean(true)  [有别于] new Boolean(true) => 这个是对象
!!false     // false 保持原样 = Boolean(false) [有别于] new Boolean(false) => 这个是对象

/**
 * 使用Boolean(value)方法可以强制转换任意值为boolean类型,
 * 除了以下六个值,其他都是自动转为true
 * undefined
 * null
 * -0
 * +0
 * NaN
 * ''(空字符串)
 *
 * 所有对象的布尔值都是true,甚至连false对应的布尔对象也是true。
 */
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(+0) // false
Boolean(-0) // false
Boolean(NaN) // false
Boolean('') // false

/**
 * ! (取反)
 *   对于[布尔类型]会将其值true和false互换
 *   [非布尔类型],js会将值先转换成布尔类型,而后取反
 *
 * !!是将表达式强制转化为bool值的运算
 *   表达式是什么值,结果就是对应的bool值
 *   【个人觉得】等同于  Boolean(value)方法 的感觉
 */