Javascript 변수 유형을 얻는 더 좋은 방법은 무엇입니까?


260

JS보다 변수 유형을 얻는 더 좋은 방법이 typeof있습니까? 당신이 할 때 잘 작동합니다 :

> typeof 1
"number"
> typeof "hello"
"string"

그러나 시도 할 때 쓸모가 없습니다.

> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"

나는 알고 instanceof있지만 사전에 유형을 알아야합니다.

> [1,2] instanceof Array
true
> r instanceof RegExp
true

더 좋은 방법이 있습니까?


1
참고 typeof new RegExp(/./); // "function"로 Chrome 의 문제는 Chrome 14에서 수정 된 것으로 보입니다.
user113716


경고 : JS를 축소하고 typescript 클래스와 같은 '사용자 정의 객체'를 사용하는 경우 아래 답변 중 일부가 n예상되는 원래 이름 대신 모호한 함수 이름을 제공합니다 . 예를 들면 constructor.name당신을 줄 수있는 n예상되는 전체 이름 대신
Simon_Weaver

답변:


221

Angus Croll은 최근 이것에 관한 흥미로운 블로그 게시물을 썼습니다.

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

그는 다양한 방법의 장단점을 살펴보고 새로운 방법 'toType'을 정의합니다.

var toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

3
여기서 흥미로운 참고 사항- "호스트"개체가 함수에 전달되는 위치가 손상 될 수 있습니다. ActiveXObject예를 들어 Internet Explorer 인스턴스
Andy E

고유 한 객체 유형 (프로토 타입 상속)을 만든 경우 "객체"보다 더 구체적인 값을 반환하려면 어떻게해야합니까? 이것은 여기서도 문제로 제기 되었지만 해결되지 않았습니다.
EleventyOne

1
타입 네이밍에 : 또는 _가 포함되어 있다면이 정규 표현식을 다음으로 확장 할 수 있습니다.match(/\s([a-z,_,:,A-Z]+)/)
masi

6
정규식에도 같은 숫자를 포함해야합니다 Uint8Array. 대신 match(/\s([^\]]+)/)무엇이든 처리해야하는 보다 일반적인 것을 고려하십시오 .
Lily Finley

2
\w대신 단어 연산자 를 사용하는 것이 좋습니다 .
kaiser

51

를 사용해보십시오 constructor.name.

[].constructor.name
new RegExp().constructor.name

모든 JavaScript와 마찬가지로 누군가는 결국 이것이 어떻게 든 악하다고 지적 할 것이므로 이를 잘 다루는 답변에 대한 링크가 있습니다.

대안은 사용하는 것입니다 Object.prototype.toString.call

Object.prototype.toString.call([])
Object.prototype.toString.call(/./)

10
nameECMAScript의 확장이며 일부 브라우저에서는 작동하지 않습니다.
Andy E

16
자바 스크립트에서 수행 된 모든 것이 어떻게 든 악하다는 의혹을 확인함으로써 투표에 찬성했습니다.
liljoshu

1
EVIL : 코드를 축소 하면 예상되는 객체 이름 대신에 constructor.name비슷한 n이름이 될 수 있습니다. 따라서 특히 프로덕션에서 축소하는 경우 조심하십시오.
Simon_Weaver

null그리고 undefined불행하게도 생성자가 없습니다.
앤드류 그림

자바 스크립트 자체는 악하다. 그리고 바보. 이 질문에 정답이 없다는 사실은 그에 대한 살아있는 증거입니다.
user2173353

38

합리적으로 좋은 형식 캡처 기능은 YUI3에서 사용하는 것입니다 .

var TYPES = {
    'undefined'        : 'undefined',
    'number'           : 'number',
    'boolean'          : 'boolean',
    'string'           : 'string',
    '[object Function]': 'function',
    '[object RegExp]'  : 'regexp',
    '[object Array]'   : 'array',
    '[object Date]'    : 'date',
    '[object Error]'   : 'error'
},
TOSTRING = Object.prototype.toString;

function type(o) {
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
};

이것은 자바 스크립트가 제공하는 많은 프리미티브를 캡처하지만 항상 TYPES객체 를 수정하여 더 많은 것을 추가 할 수 있습니다 . 참고 typeof HTMLElementCollection사파리보고에서 function, 그러나 유형 (HTMLElementCollection) 반환합니다object


31

다음 기능이 유용 할 수 있습니다.

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

또는 ES7에서 (추가 개선의 경우 의견)

function typeOf(obj) {
  const { toString } = Object.prototype;
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);

  return type.toLowerCase();
}

결과 :

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new Error) //error
typeOf(Promise.resolve()) //promise
typeOf(function *() {}) //generatorfunction
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map

오류, 약속, 생성기 함수를 알려 주신 @johnrees에게 감사드립니다.


고마워 날짜 객체에도 적용됩니다.typeOf(new Date())
James Irwin

아, 잊어 버렸어요. 고마워요.
Vix

1
그리고typeOf(Promise.resolve())//promise typeOf(function *() {})//generatorfunction
johnrees

이 답변을 typescript에서 작동시킬 수 없습니다. [ts] Cannot redeclare block-scoped variable 'toString'
DauleDK

TypeScript에 대해 확실하지 않습니다. ES7 버전을 사용해 보셨습니까? 명시 적으로 선언되지 않은 toString이 원인 일 수 있습니까?
Vix

15

또한 우리는 ipr101 에서 작은 예제를 변경할 수 있습니다

Object.prototype.toType = function() {
  return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

로 전화

"aaa".toType(); // 'string'

6
JavaScript 기본 개체를 조작하면 호환성 및 기타 이상한 문제가 발생할 수 있습니다. 라이브러리와 더 큰 프로젝트 모두에서 이것을 적게 사용하십시오!
Alexander Craggs 2016 년

9

한 줄 기능 :

function type(obj) {
    return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}

이것은 같은 결과를 제공합니다 jQuery.type()


3

Object.prototype.toString모든 객체에 적용 할 수 있습니다 .

var toString = Object.prototype.toString;

console.log(toString.call([]));
//-> [object Array]

console.log(toString.call(/reg/g));
//-> [object RegExp]

console.log(toString.call({}));
//-> [object Object]

이것은 IE를 제외하고 모든 브라우저에서 잘 작동합니다. 다른 창에서 얻은 변수에서 이것을 호출하면 그냥 뱉어집니다 [object Object].


1
@ Xeon IE에 대한 증오가 너무 크다고 생각합니다. IE9는 이전 버전보다 훨씬 나은 브라우저입니다.
Aillyn

4
@pessimopoppotamus이지만 IE9로 브라우저를 업데이트하려는 사람은 아무도 IE를 사용하지 않습니다.
Alex Turpin

1
IE 9는 올바른 방향으로 나아가는 단계이며 IE 10은 꽤 좋아 보입니다. 덧붙여, 내가 언급 한 버그는 IE 9의 회귀 (regression)였습니다. 그들은 IE 8에서 수정했습니다.
Andy E

3

내 2 ¢! 실제로, 내가 여기에 던지는 이유 중 일부는 긴 답변 목록에도 불구하고 조금 더 많은 all in one유형의 솔루션 을 제공하고 더 많은 것을 포함하도록 확장하는 방법에 대한 피드를 다시 얻는 것입니다.real types 입니다.

다음과 같은 솔루션을 사용하여 위에서 언급 한 것처럼 여기에있는 몇 가지 솔루션을 결합하고 가능한 경우 jQuery 정의 객체 의 값을 반환하기위한 수정 사항 을 통합했습니다 . 또한 기본 Object 프로토 타입에 메소드를 추가합니다. 다른 확장 프로그램을 방해 할 수 있기 때문에 종종 금기 사항이라는 것을 알고 있지만 . 이 방법이 마음에 들지 않으면 원하는 곳에서 기본 함수를 복사하고 전달할 인수 매개 변수로 모든 변수를 바꾸십시오 (예 : arguments [0]).jQueryuser bewarethis

;(function() {  //  Object.realType
    function realType(toLower) {
        var r = typeof this;
        try {
            if (window.hasOwnProperty('jQuery') && this.constructor && this.constructor == jQuery) r = 'jQuery';
            else r = this.constructor && this.constructor.name ? this.constructor.name : Object.prototype.toString.call(this).slice(8, -1);
        }
        catch(e) { if (this['toString']) r = this.toString().slice(8, -1); }
        return !toLower ? r : r.toLowerCase();
    }
    Object['defineProperty'] && !Object.prototype.hasOwnProperty('realType')
        ? Object.defineProperty(Object.prototype, 'realType', { value: realType }) : Object.prototype['realType'] = realType;
})();

그런 다음 간단히 다음과 같이 쉽게 사용하십시오.

obj.realType()  //  would return 'Object'
obj.realType(true)  //  would return 'object'

참고 : 인수에는 1 개의 인수가 있습니다. 부울 인 경우 true반환 값은 항상 소문자 입니다.

더 많은 예 :

true.realType();                            //  "Boolean"
var a = 4; a.realType();                    //  "Number"
$('div:first').realType();                   // "jQuery"
document.createElement('div').realType()    //  "HTMLDivElement"

다른 라이브러리 (Moo, Proto, Yui, Dojo 등)로 객체가 생성 된 시간을 정의하는 것과 같이 도움이 될만한 추가 사항이 있으면 언제든지 의견을 말하거나 편집하여 더 많이 사용하십시오. 정확하고 정확합니다. 또는 GitHub내가 그것을 위해 만든 롤오버 하고 알려주세요. cdn min 파일에 대한 빠른 링크도 있습니다.


2
function getType(obj) {
    if(obj && obj.constructor && obj.constructor.name) {
        return obj.constructor.name;
    }
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

내 예비 테스트에서 이것은 잘 작동합니다. 첫 번째 경우는 "new"로 생성 된 개체의 이름을 인쇄하고 두 번째 경우는 다른 모든 것을 포착해야합니다.

(8, -1)결과가 항상 시작 [object하고 끝날 것이라고 가정하기 때문에 사용 하고 ]있지만 모든 시나리오에서 이것이 사실인지는 확실하지 않습니다.


2

여기에서 가장 보편적 인 해결책은 먼저 확인 undefined하고 null먼저 전화하는 것 constructor.name.toLowerCase()입니다.

const getType = v =>
  v === undefined
    ? 'undefined'
    : v === null
      ? 'null'
      : v.constructor.name.toLowerCase();




console.log(getType(undefined)); // 'undefined'
console.log(getType(null)); // 'null'
console.log(getType('')); // 'string'
console.log(getType([])); // 'array'
console.log(getType({})); // 'object'
console.log(getType(new Set())); // `set'
console.log(getType(Promise.resolve())); // `promise'
console.log(getType(new Map())); // `map'

내가 아는 한- .constructor.name항상 문자열 값을 포함합니다. undefined / null의 경우 함수에서 적절한 문자열을 반환합니다.
Arsenowitch

감사합니다-내 의견 삭제 중…
Bergi

constructor상속 된 속성 이므로 로 생성 된 객체는 중단됩니다 Object.create(null). 고칠 정도로 간단하지만 무엇을 부를까요? "[object null]"?
traktor53

0

typeof if-else 조건에서 변수 유형을 확인하는 경우 조건은 변수 유형을 확인하는 데 사용됩니다.

if(typeof Varaible_Name "undefined")
{

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