2015-12-04 8 views
7

:私はtoString()メソッドをオーバーライドすることができますが、それはない本当にがオブジェクト型の名前を変更しないJavaScriptでオブジェクト型の名前を変更することはできますか?たとえば

var PhoneNumber = function(number) { 
    this.number = number; 
} 

Object.prototype.toString.call(new Date); // [object Date] 
Object.prototype.toString.call(new Array); // [object Array] 
Object.prototype.toString.call(new Object); // [object Object] 

は今これを検討してください。それはちょうどちょっとそれを偽装:

PhoneNumber.prototype.toString = function() { 
    return '[object PhoneNumber]'; 
} 

new PhoneNumber().toString(); // [object PhoneNumber] 

はしかし、L33T h4x0rsは私toString()方法が嘘であると私はN00Bよ知っている:

Object.prototype.toString.call(new PhoneNumber); // [object Object] 

私は関係なく、結果はになりたい何

Object.prototype.toString.call(new PhoneNumber); // [object PhoneNumber] 

はこれが可能である:toString()方法は、プロトタイプの上に上書きされていますか?

+0

をそれを把握するために私に2時間かかった;)のよう – CoderPi

答えて

6

ECMAScript 2015仕様では、この動作を制御するために使用できるよく知られたSymbolが定義されています。Symbol.toStringTag。残念ながらno browser currently support it

それがサポートされていたら、あなたはこのようにそれを使用することができます:

new PhoneNumber().toString(); // [object PhoneNumber] 
Object.prototype.toString.call(new PhoneNumber); // [object PhoneNumber] 
+0

を[V8 4.9をリリース](http://v8project.blogspot.hr /2016/01/v8-release-49.html)、この機能が利用可能であるため、今年中にノードとChromeに流入するはずです。 –

0

がObject.prototype.toStringは[[クラスを返すので:あなたの期待される動作を生成します

PhoneNumber.prototype[Symbol.toStringTag] = 'PhoneNumber'; 

]]クラスの内部プロパティであり、[[Class]]内部プロパティの値は、Date、Regexpなどのあらゆる組み込みオブジェクトに対してes5仕様で定義されています。 仕様では、このプロパティにアクセスします。 このプロパティは組み込みオブジェクトの違いを設定するために使用されているため、toStringをオーバーライドすると[[Class]]プロパティと結果always [object Object]は変更できません。 toStringの動作の詳細をさらに詳しく見るhttp://es5.github.io/#x15.2.4.2

2

はい。最初に問題を説明しましょう。あなたのクラスの.toString()は使用していませんが、toString()にはObjectという独自の定義があり、オブジェクトのtoString()は返されません。

私はあなたが*のための2つのソリューションがあります(どちらも、エッジでテストし、クロム、Firefoxの、IE9-11)

ソリューション

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

これは、ジェネリックオブジェクトのtoStringに対して壊れます。 '({})。toString()'は、呼び出しスタックを超過しました。 –

+0

@NoahFreitasその問題を修正しました – CoderPi

関連する問題