क्या डीबगिंग के लिए सार्थक आउटपुट प्रदान करने के लिए जावास्क्रिप्ट के इनस्ट्रिंग () फ़ंक्शन को ओवरराइड करना संभव है?


115

जब मैं console.log()अपने जावास्क्रिप्ट प्रोग्राम में कोई ऑब्जेक्ट करता हूं, तो मैं सिर्फ आउटपुट देखता हूं [object Object], जो यह पता लगाने में बहुत मददगार नहीं है कि यह किस वस्तु (या यहां तक ​​कि किस प्रकार की वस्तु) है।

C # में मुझे ToString()किसी ऑब्जेक्ट के डिबगर प्रतिनिधित्व को अनुकूलित करने में सक्षम होने के लिए ओवरराइड करने के लिए उपयोग किया जाता है । क्या मैं जावास्क्रिप्ट में ऐसा ही कुछ कर सकता हूं?


2
मुझे लगता है कि आउटपुट आपको यह बताने का सबसे विश्वसनीय तरीका है कि एक चर क्या है (या कम से कम बेहतर है typeof)।
एलेक्स

जवाबों:


102

आप toStringजावास्क्रिप्ट में भी ओवरराइड कर सकते हैं । उदाहरण देखें:

function Foo() 
{
}

// toString override added to prototype of Foo class
Foo.prototype.toString = function()
{
    return "[object Foo]";
}

var f = new Foo();
alert(f);  // popup displays [object Foo]

जावास्क्रिप्ट में ऑब्जेक्ट प्रकार नाम निर्धारित करने के तरीके के बारे में इस चर्चा को देखें ।


8
हालांकि यह सच है कि अलर्ट फ़ंक्शन प्रोटोटाइप की toStringसंपत्ति को ओवरराइड करने वाले फ़ंक्शन का रिटर्न मूल्य Object.prototype.toString.call(f)प्रदर्शित करेगा , अभी भी प्रदर्शित करेगा [object Object]
फ्रेडरिक क्राउटवल्ड

14
'Object.prototype.toString.call (f) अभी भी [ऑब्जेक्ट ऑब्जेक्ट] प्रदर्शित करेगा।' हाँ, क्योंकि यह 'Foo.prototype.toString' की तुलना में पूरी तरह से अलग कार्य है, योग्य है।
त्रिनको

5
अगर मेरे जैसा कोई और यहाँ समाप्त होता है, तो आप Object.prototype.toString.call व्यवहार को अनुकूलित करने के लिए ES6 में Sybmol.toStringTag का उपयोग कर सकते हैं। developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
TLadd

32

toStringअपनी वस्तु या प्रोटोटाइप के लिए पहला ओवरराइड :

var Foo = function(){};
Foo.prototype.toString = function(){return 'Pity the Foo';};

var foo = new Foo();

फिर वस्तु के स्ट्रिंग प्रतिनिधित्व को देखने के लिए स्ट्रिंग में बदलें:

//using JS implicit type conversion
console.log('' + foo);

यदि आपको अतिरिक्त टाइपिंग पसंद नहीं है, तो आप एक फ़ंक्शन बना सकते हैं जो कंसोल के लिए इसके तर्कों का स्ट्रिंग प्रतिनिधित्व करता है:

var puts = function(){
    var strings = Array.prototype.map.call(arguments, function(obj){
        return '' + obj;
    });
    console.log.apply(console, strings);
};

उपयोग:

puts(foo)  //logs 'Pity the Foo'

puts(foo, [1,2,3], {a: 2}) //logs 'Pity the Foo 1,2,3 [object Object]'

अपडेट करें

E2015 इस सामान के लिए ज्यादा अच्छे वाक्य रचना प्रदान करता है, लेकिन आप की तरह एक transpiler का उपयोग करना होगा कोलाहल :

// override `toString`
class Foo {
  toString(){
    return 'Pity the Foo';
  }
}

const foo = new Foo();

// utility function for printing objects using their `toString` methods
const puts = (...any) => console.log(...any.map(String));

puts(foo); // logs 'Pity the Foo'

6
कंसोल.लॉग ('' + फू); यह वह समस्या थी जब तक मैंने आपके जवाब तक पहुंचने तक कोई भी कार्यान्वयन कार्यान्वयन नहीं देखा।
अहमादलिबालोच

13

ब्राउज़र जेएस में डीबग करने योग्य आउटपुट प्राप्त करने का एक आसान तरीका सिर्फ ऑब्जेक्ट को JSON में क्रमबद्ध करना है। तो आप जैसे कॉल कर सकते थे

console.log ("Blah: " + JSON.stringify(object));

एक उदाहरण के लिए, alert("Blah! " + JSON.stringify({key: "value"}));पाठ के साथ एक चेतावनी पैदा करता हैBlah! {"key":"value"}


यह बहुत आसान है। आउटपुट थोड़ा बड़ा हो सकता है जिसकी मैं कल्पना करता हूं, लेकिन चुटकी में काम करता है!
devios1

@ देव हैंडी, लेकिन स्ट्रीडिंग () को ओवरराइड नहीं करता है।
दानस्केलस्कु

10

यदि आप नोड का उपयोग कर रहे हैं तो यह विचार करने लायक हो सकता है util.inspect

var util = require('util')

const Point = {
  x: 1,
  y: 2,
  [util.inspect.custom]: function(depth) { return `{ #Point ${this.x},${this.y} }` }

}

console.log( Point );

इससे उपज होगी:

{ #Point 1,2 }

जबकि संस्करण का निरीक्षण किए बिना प्रिंट:

{ x: 1, y: 2 }

6

बस toString()विधि को ओवरराइड करें ।

सरल उदाहरण:

var x = {foo: 1, bar: true, baz: 'quux'};
x.toString(); // returns "[object Object]"
x.toString = function () {
    var s = [];
    for (var k in this) {
        if (this.hasOwnProperty(k)) s.push(k + ':' + this[k]);
    }
    return '{' + s.join() + '}';
};
x.toString(); // returns something more useful

जब आप एक नए प्रकार को परिभाषित करते हैं तो यह और भी बेहतर होता है:

function X()
{
    this.foo = 1;
    this.bar = true;
    this.baz = 'quux';
}

X.prototype.toString = /* same function as before */

new X().toString(); // returns "{foo:1,bar:true,baz:quux}"

9
यह कोड ओपी के कंसोल.लॉग समस्या को हल नहीं करता है, कम से कम नोड.जेएस v0.10.*या क्रोम में नहीं Version 32.0.1700.102। सीधे सीधे (लंगड़ा) कॉल करने के लिए या टाइप कॉर्शन (लैमर) का उपयोग करते हुए, इस के साथ काम करेगा, कंसोल [/ info | log /] का उपयोग करता है पुराने प्री-मोड toString।
james_womack

1
यह अब 2019 है और दोनों नोड्ज और क्रोम सुंदर-प्रिंट ऑब्जेक्ट्स को अपने दम पर, इसलिए जबरदस्ती (जब आप ऑब्जेक्ट को एक स्ट्रिंग में जोड़ते हैं) एकमात्र उपयोग मामला है जिसे आप इस सवाल को मानेंगे।
केल्सुन

6

यदि ऑब्जेक्ट अपने आप से परिभाषित होता है तो आप हमेशा एक स्ट्रींग ओवरराइड जोड़ सकते हैं।

//Defined car Object
var car = {
  type: "Fiat",
  model: 500,
  color: "white",
  //.toString() Override
  toString: function() {
    return this.type;
  }
};

//Various ways to test .toString() Override
console.log(car.toString());
console.log(car);
alert(car.toString());
alert(car);

//Defined carPlus Object
var carPlus = {
  type: "Fiat",
  model: 500,
  color: "white",
  //.toString() Override
  toString: function() {
    return 'type: ' + this.type + ', model: ' + this.model + ', color:  ' + this.color;
  }
};

//Various ways to test .toString() Override
console.log(carPlus.toString());
console.log(carPlus);
alert(carPlus.toString());
alert(carPlus);



3

कस्टम ऑब्जेक्ट या क्लास में 'Symbol.toStringTag' प्रॉपर्टी जोड़ें ।

स्ट्रिंग मान जो इसे सौंपा गया है वह इसका डिफ़ॉल्ट स्ट्रिंग विवरण होगा क्योंकि यह Object.prototype.toString()विधि द्वारा आंतरिक रूप से एक्सेस किया जाता है।

उदाहरण के लिए:

class Person {
  constructor(name) {
    this.name = name
  }
  get [Symbol.toStringTag]() {
    return 'Person';
  }
}

let p = new Person('Dan');
Object.prototype.toString.call(p); // [object Person]

कुछ जावास्क्रिप्ट प्रकार जैसे कि मैप्स और प्रॉमिस में एक अंतर्निहित toStringTagप्रतीक होता है

Object.prototype.toString.call(new Map());       // "[object Map]"
Object.prototype.toString.call(Promise.resolve()); // "[object Promise]"

क्योंकि Symbol.toStringTagएक प्रसिद्ध प्रतीक है , हम इसे संदर्भित कर सकते हैं और सत्यापित कर सकते हैं कि उपरोक्त प्रकारों में Symbol.toStringTag संपत्ति है -

new Map()[Symbol.toStringTag] // 'Map'
Promise.resolve()[Symbol.toStringTag] // 'Promise'

क्या यह एक साथ प्राप्त toString()करने का एकमात्र तरीका है function MyObj() {} Object.prototype.toString.call(new MyObj()) // "[object MyObj]"
टॉनिक्स

1
@tonix - मुझे ऐसा लगता है ... अगर कोई और तरीका है, तो कृपया मुझे बताएं;)
Danield

0

Chrome कंसोल लॉग आपको ऑब्जेक्ट का निरीक्षण करने की अनुमति देता है।


हां, यह सच है अगर मैं सिर्फ ऑब्जेक्ट का उत्पादन करता हूं, जो कि आसान है। हालाँकि कभी-कभी मैं इसे एक स्ट्रिंग के हिस्से के रूप में आउटपुट करना चाहता हूं जिसका उपयोग मैं अन्य डेटा को करने के लिए कर सकता हूं और यह अच्छा होगा यदि मैं उस फॉर्म को किसी तरह से अनुकूलित कर सकता हूं।
devios1

6
मुझे अभी पता चला है कि आप एक स्ट्रिंग के साथ इनलाइन आउटपुट आउटपुट इनलाइन में अतिरिक्त तर्कों का उपयोग कर सकते हैं console.log("this is my object:", obj):।
devios1

0

-इस ऑपरेशन को पूरा होने में बहुत समय लगता है, और इसका उपयोग मोज़िला डॉक्स के अनुसार हतोत्साहित करता है: https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos-globales/Object/proto

-आमतौर पर, आधुनिक ब्राउज़रों को हटाए गए .prototype और ECMA6 इसके बजाय उचित__proto__ का उपयोग करके निर्दिष्ट करते हैं।

उदाहरण के लिए, यदि आप आप स्वयं वस्तु को परिभाषित कर रहे geoposition आप बुलाना चाहिए __proto__ के बजाय संपत्ति .prototype :

var  geoposition = {

        lat: window.pos.lat,
        lng: window.pos.lng
    };

geoposition.__proto__.toString = function(){ return "lat: "+this.lat+", lng: "+this.lng }
console.log("Searching nearby donations to: "+geoposition.toString());

0

यहाँ एक उदाहरण दिया गया है कि मैप ऑब्जेक्ट को कैसे सख्त किया जाए:

  Map.prototype.toString = function() {

    let result = {};

    this.forEach((key, value) => { result[key] = value;});

    return JSON.stringify(result);
  };

-1

आप किसी भी कस्टम ऑब्जेक्ट को अपने स्वयं के तरीकों को दे सकते हैं, या एक सामान्य लिख सकते हैं जिसे आप उस ऑब्जेक्ट पर कॉल कर सकते हैं जिसे आप देख रहे हैं-

Function.prototype.named= function(ns){
    var Rx=  /function\s+([^(\s]+)\s*\(/, tem= this.toString().match(Rx) || "";
    if(tem) return tem[1];
    return 'unnamed constructor'
}

function whatsit(what){
    if(what===undefined)return 'undefined';
    if(what=== null) return 'null object';
    if(what== window) return 'Window object';
    if(what.nodeName){
        return 'html '+what.nodeName;
    }
    try{
        if(typeof what== 'object'){
            return what.constructor.named();
        }
    }
    catch(er){
        return 'Error reading Object constructor';
    }
    var w=typeof what;
    return w.charAt(0).toUpperCase()+w.substring(1);
}

-1

ओवरराइड करने के बजाय toString(), यदि आप प्रोटोटाइप जावास्क्रिप्ट लाइब्रेरी शामिल करते हैं, तो आप Object.inspect()बहुत अधिक उपयोगी प्रतिनिधित्व प्राप्त करने के लिए उपयोग कर सकते हैं ।

अधिकांश लोकप्रिय रूपरेखाओं में कुछ इसी तरह का समावेश होता है।


-1

आप JS में विस्तार या ओवरराइड कर सकते हैं

String.prototype.toString = function() {
    return this + "..."
}
document.write("Sergio".toString());


यह 2011 के उत्तरों में कुछ भी कैसे जोड़ता है जो समान समाधान देते हैं?
दानस्केलस्कु

-3
A simple format Date function using Javascript prototype, it can be used for your purpose

https://gist.github.com/cstipkovic/3983879 :

Date.prototype.formatDate = function (format) {
    var date = this,
        day = date.getDate(),
        month = date.getMonth() + 1,
        year = date.getFullYear(),
        hours = date.getHours(),
        minutes = date.getMinutes(),
        seconds = date.getSeconds();

    if (!format) {
        format = "MM/dd/yyyy";
    }

    format = format.replace("MM", month.toString().replace(/^(\d)$/, '0$1'));

    if (format.indexOf("yyyy") > -1) {
        format = format.replace("yyyy", year.toString());
    } else if (format.indexOf("yy") > -1) {
        format = format.replace("yy", year.toString().substr(2, 2));
    }

    format = format.replace("dd", day.toString().replace(/^(\d)$/, '0$1'));

    if (format.indexOf("t") > -1) {
        if (hours > 11) {
            format = format.replace("t", "pm");
        } else {
            format = format.replace("t", "am");
        }
    }

    if (format.indexOf("HH") > -1) {
        format = format.replace("HH", hours.toString().replace(/^(\d)$/, '0$1'));
    }

    if (format.indexOf("hh") > -1) {
        if (hours > 12) {
            hours -= 12;
        }

        if (hours === 0) {
            hours = 12;
        }
        format = format.replace("hh", hours.toString().replace(/^(\d)$/, '0$1'));
    }

    if (format.indexOf("mm") > -1) {
        format = format.replace("mm", minutes.toString().replace(/^(\d)$/, '0$1'));
    }

    if (format.indexOf("ss") > -1) {
        format = format.replace("ss", seconds.toString().replace(/^(\d)$/, '0$1'));
    }

    return format;
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.