『翻译』"typeof null是什么?"以及其它让我们感到困惑的JavaScript类型

Read the original


前言

typeof运算符在JavaScript中用来判断一个数据的类型,它返回一个字符串。比如,我们想知道123的数据类型,我们可能这样写:

1
typeof 123

它会返回123的数据类型,那么应该是”number”。除了”number”,typeof运算符还会返回其他6种结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
typeof 123 // "number"
typeof "abc" // "string"
typeof true // "boolean"
typeof {a: 1} // "object"
typeof function foo() {} // "function"
typeof undefined // "undefined"
typeof Symbol('foo') // "symbol"

从上面的例子中可以看出,typeof运算符使用十分简单。但是,这只是很少的一部分案例,它们很容易让人误解和混淆typeof运算符究竟是怎样运作的。

typeof typeof 123是什么类型?

1
typeof typeof 123 //"string"

typeof运算符返回的值是什么类型?好的,typeof操作符总是以字符串的形式返回传递给它的值的数据类型。如果去获取typeof计算后返回的值,比如一个数字,它将会是"number"。这意味着,无论结果是什么类型,我们去判断一个typeof [any operand],永远都是返回字符串。

typeof NaN是什么类型?

1
typeof NaN //"number"

NaN代表某个值不是一个数字,但出乎意料的是,它是”number”类型。原因是这样的,在计算机内部,NaN是以数字类型储存的。然而,它是一个不能用实际数字来表示的数值类型的值。所以它叫“Not a Number”,这并不意味着它不是数值类型。相反,它意味着这个值不能用数值表示。

这也解释了为什么NaN的值都不相等。比如:

1
2
3
4
const NaN1 = 2 * "abc";
const NaN2 = 2 * "abc";
NaN1 === NaN2 // false

上面两个NaN的值不相等,因为它们不能用两个相同的数字来表示。

typeof [1, 2, 3]是什么类型?

1
typeof [1,2,3] // "object"

对数组使用typeof会得到”object”。在JavaScript中, 数组其实是一个对象,只是拥有一些特殊的行为和能力。比如,数组拥有Array.prototype.length属性,它将会返回数组有多少个元素。数组也有一些特殊的方法,比如:Array.prototype.push()Array.prototype.unshift()(可以参考JavaScript数组方法)。

区别数组和对象,我们可以使用Array.isArray()方法:

1
2
Array.isArray( [1,2,3] ) // true
Array.isArray( { a: 1 } ) // false

typeof null是什么类型?

1
typeof null // "object"

null的值从技术上来说和objectnumber一样,都是最基本的值,按理来说,null的类型也应该是”null”。然而并非如此,因为JavaScript最初设计时出了一点意外。

在JavaScript最初设计时,一个值有两个部分组成:它的类型标签和实际的值。有5个类型标签可以使用,而且对象类型的引用指向0null的值始终指向NULL指针,它在大部分平台都是用0x00来表示。由于这种相似性,null就用过0类型标签来表示,所以符合对象的引用。

typeof class Foo {}是什么类型?

1
typeof class Foo {} // "function"

最后,我们讲一下类(Classes)。类在ES6中的介绍是:一个更好的语法为原型继承服务。在将类之前,我们先创建一个可继承的对象,我们要用到函数。

1
2
3
4
5
6
7
function Dog() { };
Dog.prototype.bark = function() {
alert('woof!');
}
const snoopy = new Dog();
snoopy.bark(); //alert('woof!');

使用类,我们可以用同样的方式创建一个类似的对象:

1
2
3
4
5
6
7
8
class Dog {
bark() {
alert("woof!");
}
}
const snoopy = new Dog();
snoopy.bark() // alert("woof!")

然而,JavaScript的类只是一个被语法糖包裹的函数方法。实际上创建了一个同样的函数,但是作者的写法不同,只是看起来个简洁。这就是为什么typeof一个类,得到的仍然是”Function”。

本文作者:余震(Freak)
本文出处:Rockjins Blog
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN许可协议。转载请注明出处!

坚持,您的支持将鼓励我继续爬下去!