Symbol.toStringTag
是一个内置symbol
,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型,通常只有内置的Object.prototype.toString()
方法采取读取这个标签并把它包含在自己的返回值里。
typeof Symbol.toStringTag;//symbol
很多内置对象没有toStringTag
属性,但也能被toString()
方法识别,如String,Array,Number,Boolean,undefined,null
另一些对象能被toString()
识别是因为引擎为它们设置好了toStringTag
,如Map,GeneratorFunction,Promise
判断一个变量是否为数组,我们可以使用以下方法:
Object.prototype.toString.call(props) === '[object Array]'
我们也可以为自己定义的对象定义Symbol.toStringTag
属性。
const str = '123';
Object.prototype.toString.call(str); // "[object String]"
str[Symbol.toStringTag] // undefined
const map = new Map();
Object.prototype.toString.call(map); // "[object Map]"
map[Symbol.toStringTag] // "Map"
function Teacher(name) {
this.name = name
}
Teacher.prototype[Symbol.toStringTag] = 'Teacher'
方法调用:
const teacher = new Teacher('Jason')
console.log(teacher.toString()) //[object Teacher]
console.log(Object.prototype.toString.call(teacher)) //[object Teacher]
这个影响了对象自身的toString
方法,当然可以通过重写来覆盖。
Teacher.prototype.toString = function() {
return this.name
}
console.log(teacher.toString()) //Jason
这个属性也有一定的破坏性,它并不阻止你为哪些对象设置该属性,那么如果我为Array对象设置该属性,那么就修改了原来的返回结果。
Array.prototype[Symbol.toStringTag] = 'Hello'
console.log(Object.prototype.toString.call([])) //[object Hello]
所以,使用时一定要小心,千万不要修改内建对象。
class Car {
constructor(model, year) {
this.model = model;
this.year = year;
}
}
const smart = new Car('Benz', '2018');
smart instanceof Car // true
Object.prototype.toString.call(smart) // "[object Object]"
// 我们希望toStirng()方法能直接返回"[object Car]",那么可以使用Symbol.toStringTag
class Car {
constructor(model, year) {
this.model = model;
this.year = year;
}
get [Symbol.toStringTag]() {
return "Car";
}
}
const smart = new Car('Benz', '2018');
smart instanceof Car // true
Object.prototype.toString.call(smart) // "[object Car]"