toString
toString 可以用来判断数据类型. 可以把它看作是 typeof 的加强版,因为它不仅可以检测原始类型,还可以区分 object。
[[Class]]
我们需要先来说一下 [[Class]] 这个内部属性(只要是 [[]] 都是 js的内部属性,是不能够直接访问的),你不要认为它是与类有关系的内部属性,你可以把它看作是一种分类的方法。我们可以间接地通过在这个值上借用默认的 Object.prototype.toString() 来调用展示。
Object.prototype.toString.call([1,2,3]);
Object.prototype.toString.call(
看,我们可以得到不同于 typeof 的 object。
其实,[[Class]] 对应的是关联这个值的内建的原生类型构造器。
null、undefined
注意了,上面说了 [[Class]] 对应的原生构造器,但是 null、undefined 是没有的。
Object.prototype.toString.call(null);
Object.prototype.toString.call(undefined);
明明 null、undefined 是没有原生构造器的,那么为什么 [[Class]] 还能返回类型,这跟实现有关,在算法中其实是单独规定了 null、undefined 的行为。
string、number、boolean
Object.prototype.toString.call(1);
Object.prototype.toString.call('1');
Object.prototype.toString.call(true);
除了 null、undefined 没有原生构造器,其他的类型都有。虽然这里使用的是 原始数据类型。但是在算法执行过程中,是会启用简单数据类型的封箱(看包装类型章节)操作,也就是说,它们实际上会用它们的构造器。
toString 算法
上面的疑惑你讲会在这里得到解答。在 toString 内部是使用的 this(this章节) ,从这里我们也能看出,真正的使用 this 是多么的强大,而不是传入对象环境(题外话)。
- 如果 this 值是 undefined, 就返回 [object Undefined].
- 如果 this 值是 null, 就返回 [object Null].
- 让 O 成为 ToObject(this).
- 让 class 成为 O 的内部属性 [[Class]] 的值。
- 最后返回由 ‘[object’ 和 class 和 ‘]’ 三部分组成的字符串。
看到了吗 1. 2点的处理。 以及 3 封箱的一个操作。
Symbol.toStringTag
上面的都是原生类型。String、Number、Boolean、Array、Object、Function、RegExp…
我们可以自定义类型。我们需要借助 Symbol.toStringTag. 原生类型上是没有这个属性的,但是对于大多数的特定环境的对,都会有这么一个属性. 比如:window、XMLHttpRequest。
let person = {
[Symbol.toStringTag]: 'Person'
}
Object.prototype.toString.call(person);
小问题。
我们借用 Object.prototype.toString 可以获取类型。我们也可以使用 {}.toString 这种获取。但是注意:如果我们重写了 {} 上的 toString 方法,就会遮蔽 Object.prototype 上的 toString 属性。也就不能正确的返回类型
let obj = {
toString() {
return '[object Number]';
}
};
obj.toString();
但是我们使用 Object.prototype 上的 toString, 因为是内置的,所以一定遮蔽不了。
|