디버깅을위한 의미있는 출력을 제공하기 위해 JavaScript의 toString () 함수를 재정의 할 수 있습니까?


115

console.log()JavaScript 프로그램에서 객체 일 때 출력 만 [object Object]보는데, 어떤 객체 (또는 어떤 유형의 객체)인지 파악하는 데별로 도움이되지 않습니다.

C #에서는 ToString()개체의 디버거 표현을 사용자 지정할 수 있도록 재정의 하는 데 익숙 합니다. JavaScript에서 비슷한 작업이 있습니까?


2
출력은 변수가 무엇을 보유하고 있는지 (또는 적어도 typeof) 를 알려주는 가장 신뢰할 수있는 방법이라는 것을 알았습니다 .
alex

답변:


103

toStringJavascript에서도 재정의 할 수 있습니다 . 예를보십시오 :

function Foo() {}

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

var f = new Foo();
console.log("" + f); // console displays [object Foo]

JavaScript에서 객체 유형 이름을 결정하는 방법에 대한 토론을 참조하십시오 .


8
true 인 동안 경고 함수는 prototype toString속성을 재정의하는 함수의 반환 값을 Object.prototype.toString.call(f)표시하지만은 계속 표시됩니다 [object Object].
Frederik Krautwald

14
'Object.prototype.toString.call (f)은 여전히 ​​[object Object]를 표시합니다.' 예, 'Foo.prototype.toString'과는 완전히 다른 기능이기 때문입니다.
Triynko 2016 년

5
저와 같은 다른 사람이 여기에 올 경우 ES6의 Sybmol.toStringTag를 사용하여 Object.prototype.toString.call 동작을 사용자 지정할 수 있습니다. 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는이 항목에 대해 훨씬 더 좋은 구문을 제공하지만 Babel 과 같은 트랜스 파일러를 사용해야합니다 .

// 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
console.log ( ''+ foo); 이것은 내가 귀하의 답변에 도달 할 때까지 toString 구현을 보지 못한 문제였습니다.
ahmadalibaloch

13

브라우저 JS에서 디버깅 가능한 출력을 얻는 쉬운 방법은 객체를 JSON으로 직렬화하는 것입니다. 그래서 당신은 다음과 같이 전화를 걸 수 있습니다.

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

예를 들어, alert("Blah! " + JSON.stringify({key: "value"}));텍스트가 포함 된 경고를 생성합니다.Blah! {"key":"value"}


꽤 편리합니다. 출력은 내가 상상하는 약간 거대 할 수 있지만 핀치에서 작동합니다!
devios1 2014-06-10

@dev Handy이지만 toString ()을 재정의하지 않습니다.
Dan Dascalescu

10

Node를 사용하는 경우 고려해 볼 가치가 있습니다 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
이 코드는 OP의 console.log 문제를 해결하지 못합니다. 적어도 node.js v0.10.*또는 Chrome 에서는 해결되지 않습니다 Version 32.0.1700.102. toString을 직접 호출하는 동안 (lame) 또는 type coercion (lamer)을 사용하는 동안 이것으로 작동하지만 console [/ info | log /]은 이전 pre-mod toString을 사용합니다.
james_womack 2014 년

1
이제 2019 년이고 nodejs와 chrome pretty-print 객체가 모두 자체적으로 있으므로 강제 (객체를 문자열에 추가 할 때)는 내가 생각하는이 질문을 Google에 검색 할 유일한 사용 사례입니다.
Klesun

6

객체가 직접 정의 된 경우 항상 toString 재정의를 추가 할 수 있습니다.

//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]

Maps 및 Promises와 같은 일부 Javascript 유형에는 toStringTag정의 된 기본 제공 기호가 있습니다.

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

때문에 Symbol.toStringTagA는 잘 알려진 기호는 , 우리는 그것을 참조하고 위의 유형이 Symbol.toStringTag 속성이 할 수 있는지 확인할 수 있습니다 -

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

이것은 toString()직접 재정의와 함께 달성하는 유일한 방법 function MyObj() {} Object.prototype.toString.call(new MyObj()) // "[object MyObj]"입니까?
tonix

1
@tonix-그렇게 생각합니다 ... 다른 방법이 있으면 알려주세요;)
Danield

0

Chrome 콘솔 로그를 사용하면 개체를 검사 할 수 있습니다.


예, 객체 만 출력하면 사실입니다. 편리합니다. 그러나 때로는 다른 데이터를 포함하는 데 사용할 수있는 문자열의 일부로 출력하고 싶습니다. 어떤 방식 으로든 해당 양식을 사용자 정의 할 수 있다면 좋을 것입니다.
devios1 2014-06-10

6
방금 console.log에서 추가 인수를 사용하여 문자열을 사용하여 객체를 인라인으로 출력 할 수 있음을 발견했습니다 console.log("this is my object:", obj)..
devios1

0

-이 작업은 완료하는 데 많은 시간이 걸리며 mozilla 문서에 따라 사용하지 않는 것이 좋습니다. https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Object/proto

-분명히 현대 브라우저는 .prototype을 사용하지 않으며 ECMA6는 대신 proper__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 객체를 문자열 화하는 방법의 예입니다.

  Map.prototype.toString = function() {

    let result = {};

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

    return JSON.stringify(result);
  };

-1

사용자 지정 개체에 고유 한 toString 메서드를 제공하거나보고있는 개체에서 호출 할 수있는 일반 개체를 작성할 수 있습니다.

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

를 재정의하는 대신 Prototype JavaScript LibrarytoString() 를 포함 하면을 사용 하여 훨씬 더 유용한 표현을 얻을 수 있습니다 .Object.inspect()

가장 많이 사용되는 프레임 워크에는 유사한 것이 포함됩니다.


-1

JS에서 확장하거나 재정의 할 수 있습니다.

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


이것은 동일한 솔루션을 제공하는 2011 답변에 어떻게 추가합니까?
Dan Dascalescu

-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;
};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.