例如:
Object.prototype.toString.call(new Date); // [object Date]
Object.prototype.toString.call(new Array); // [object Array]
Object.prototype.toString.call(new Object); // [object Object]
现在考虑一下:
var PhoneNumber = function(number) {
this.number = number;
}
我可以覆盖toString()
方法,但它不会真正重命名对象类型。它只是假装它:
PhoneNumber.prototype.toString = function() {
return '[object PhoneNumber]';
}
new PhoneNumber().toString(); // [object PhoneNumber]
然而,l33t h4x0rs知道我的toString()
方法是谎言而且我是n00b:
Object.prototype.toString.call(new PhoneNumber); // [object Object]
无论在原型上覆盖toString()
方法,我希望得到的结果是什么:
Object.prototype.toString.call(new PhoneNumber); // [object PhoneNumber]
这可能吗?
答案 0 :(得分:6)
ECMAScript 2015规范定义了一个众所周知的Symbol
,可用于控制此行为:Symbol.toStringTag
。不幸的是no browser currently support it。
支持后,您就可以像这样使用它:
PhoneNumber.prototype[Symbol.toStringTag] = 'PhoneNumber';
这将产生您预期的行为:
new PhoneNumber().toString(); // [object PhoneNumber]
Object.prototype.toString.call(new PhoneNumber); // [object PhoneNumber]
答案 1 :(得分:2)
是。但是,让我先解释一下这个问题:你没有使用你班级的.toString()
,但是toString()
Object
的{{1}}有它自己的定义并且没有返回toString()
你的对象。
我有两个解决方案* :(两者均在Edge,Chrome,Firefox,IE9-11中测试过)
解决方案A
Object.prototype.toString = (function(f) {
return function() {
return (this.toString === Object.prototype.toString
|| /\{\s*\[native code\]\s*\}/.test(this.toString.toString())
) ? f.call(this) : this.toString()
}
})(Object.prototype.toString) // or just {}.toString
var PhoneNumber = function(number) {
this.number = number;
}
PhoneNumber.prototype.toString = function() {
return '[object PhoneNumber]';
}
document.writeln(Object.prototype.toString.call(new PhoneNumber))
document.writeln(Object.prototype.toString.call(Function()))
document.writeln(Object.prototype.toString.call(Array()))
document.writeln(Object.prototype.toString.call(window))
document.writeln(Object.prototype.toString.call(new Date))
document.writeln(Object.prototype.toString.call(1))
document.writeln(Object.prototype.toString.call(null))
document.writeln(Object.prototype.toString.call(""))
document.writeln(Object.prototype.toString.call(document))
document.writeln(Object.prototype.toString.call(document.createElement("div")))
document.writeln(Object.prototype.toString.call(Object()))
document.writeln(({}).toString()) // check
解决方案B
Object.prototype.toString = (function(f) {
return function() {
return (typeof this._toString === 'undefined') ? f.call(this) : this._toString()
}
})(Object.prototype.toString)
var PhoneNumber = function(number) {
this.number = number;
}
PhoneNumber.prototype._toString = function() {
return '[object PhoneNumber]';
}
document.writeln(Object.prototype.toString.call(new PhoneNumber))
document.writeln(Object.prototype.toString.call(Function()))
document.writeln(Object.prototype.toString.call(Array()))
document.writeln(Object.prototype.toString.call(window))
document.writeln(Object.prototype.toString.call(new Date))
document.writeln(Object.prototype.toString.call(1))
document.writeln(Object.prototype.toString.call(null))
document.writeln(Object.prototype.toString.call(""))
document.writeln(Object.prototype.toString.call(document))
document.writeln(Object.prototype.toString.call(document.createElement("div")))
document.writeln(Object.prototype.toString.call(Object()))
document.writeln(({}).toString()) // check
答案 2 :(得分:0)
因为Object.prototype.toString返回类的[[Class]]内部属性,[[Class]]内部属性的值由es5规范定义,用于每种内置对象,如Date,Regexp。 。 在规范中,您找不到任何方法来访问此属性。 此属性用于设置内置对象之间的差异,因此重写toString不能更改[[Class]]属性,结果始终为[object Object]。 更详细的解决方法如何工作http://es5.github.io/#x15.2.4.2