2015-12-04 12 views
7

उदाहरण के लिए:जावास्क्रिप्ट में किसी ऑब्जेक्ट प्रकार का नाम बदलना संभव है?

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] 

मैं परिणाम चाहते हैं क्या हो सकता है, की परवाह किए बिना

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

यह संभव है: toString() विधि प्रोटोटाइप पर ओवरराइट जा रहा है?

+0

मैं यह काम कर दिया;) – CoderPi

उत्तर

6

ईसीएमएस्क्रिप्ट 2015 spec एक प्रसिद्ध 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] 
+0

के रूप में [वी 8 रिलीज 4.9] (http://v8project.blogspot.hr /2016/01/v8-release-49.html) यह सुविधा उपलब्ध है, इसलिए इसे इस वर्ष कभी-कभी नोड और क्रोम में घूमना चाहिए। –

0

Object.prototype.toString रिटर्न क्योंकि [[क्लास ]] कक्षा की आंतरिक संपत्ति, और [[वर्ग]] आंतरिक संपत्ति का मूल्य ईएस 5 विनिर्देश द्वारा परिभाषित किया गया है जैसे कि सभी प्रकार की अंतर्निर्मित वस्तु जैसे दिनांक, Regexp .. और विनिर्देश में आपको कोई रास्ता नहीं मिल रहा है इस संपत्ति का उपयोग करें। यह संपत्ति अंतर्निहित वस्तुओं के बीच अंतर निर्धारित करने के लिए उपयोग कर रही है, इसलिए ओवरराइड करने के लिए स्ट्रिंग [[वर्ग]] संपत्ति और परिणाम हमेशा [ऑब्जेक्ट ऑब्जेक्ट] नहीं बदल सकता है। अधिक विस्तृत कैसे करें toString काम करता है http://es5.github.io/#x15.2.4.2

2

हां। लेकिन मुझे पहले समस्या की व्याख्या करने दें: आप अपने वर्ग के .toString() का उपयोग नहीं कर रहे हैं, लेकिन toString()Object में इसकी अपनी परिभाषा है और यह आपके ऑब्जेक्ट की toString() वापस नहीं लौटाती है।

मैं तुम्हारे लिए * दो समाधान है: (दोनों एज में परीक्षण किया, क्रोम, फायरफॉक्स, 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

समाधान बी

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() 'के परिणामस्वरूप एक कॉल स्टैक त्रुटि से अधिक हो जाएगा। –

+0

@ नोहाफ्रेटास ने उस मुद्दे को ठीक किया – CoderPi

संबंधित मुद्दे