JavaScript에서 객체 값이 어떤 내장 유형에 속하는지 확인하는 가장 신뢰할 수 있는 방법은 Object.prototype.toString 메서드를 사용하는 것입니다.
var arr = []; console.log(Object.prototype.toString.call(arr)) //"[object Array]"
이 글에서는 toString 메소드가 이를 수행하는 방법과 원리가 무엇인지에 대해 이야기하겠습니다.
ECMAScript 3
ES3에서 Object.prototype.toString 메소드의 사양은 다음과 같습니다.
15.2.4.2 Object.prototype.toString()
toString 메소드가 호출되면 다음 단계가 수행됩니다.
1. 이 객체의 [[Class]] 속성 값을 가져옵니다.
2. 세 개의 문자열 "[object", 첫 번째 단계의 연산 결과 Result(1), "]" 연결 후의 새 문자열을 계산합니다.
3. 두 번째 단계 Result(2)의 연산 결과를 반환합니다.
[[클래스]]는 모든 객체(네이티브 객체와 호스트 객체)가 갖고 있는 내부 속성입니다. 사양에서는 [[클래스]]를 이렇게 정의합니다
内部属性 | 描述 |
---|---|
[[Class]] | 一个字符串值,表明了该对象的类型. |
그런 다음 그는 다음과 같이 설명했습니다.
모든 내장 개체의 [[Class]] 속성 값은 이 사양에 의해 정의됩니다. 모든 호스트 개체의 [[Class]] 속성 값은 [[Class]도 포함하여 임의의 값이 될 수 있습니다. 내장 객체 ] 속성에 의해 사용됩니다. [[Class]] 속성의 값은 기본 객체가 속한 내장 유형을 결정하는 데 사용될 수 있습니다. 이 사양은 다른 방법을 제공하지 않습니다. Object.prototype.toString 메소드를 통해 프로그램이 속성 값에 액세스하도록 합니다(15.2.4.2 참조).
즉, 내부 속성 [[class]의 값인 Object.prototype.toString 메서드에서 반환된 문자열 앞의 고정된 "[object" 및 뒤의 고정된 "]"를 제거합니다. ], 객체 유형을 결정하는 목적이 달성되었습니다. 이를 위해 jQuery의 도구 메소드 $.type()이 사용됩니다.
ES3의 사양 문서에는 [[class]] 내부 속성의 유형이 몇 가지인지 요약되어 있지 않지만, [[class]에는 총 10개의 값이 있습니다. ] 기본 개체의 내부 속성은 각각 "Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object", "RegExp", "String"입니다. .
ECMAScript 5
ES5.1에서는 사양이 더 자세하게 작성되는 것 외에도 Object.prototype.toString 메서드 정의와 Object의 [[class]] 내부 속성에 일부 변경 사항이 있습니다. 프로토타입.toString 메소드는 다음과 같습니다:
15.2.4.2 Object.prototype.toString ( )
toString 메소드가 호출되면 다음 단계가 수행됩니다.
이 값이 정의되지 않은 경우 "[객체 정의되지 않음]"을 반환합니다.
이 값이 null이면 "[object Null]"을 반환합니다.
O를 ToObject(this) 호출의 결과로 둡니다.
클래스를 O의 내부 속성 [[클래스]]의 값으로 둡니다.
세 문자열 "[object ", class 및 "]"를 연결한 후 새 문자열을 반환합니다.
ES3보다 1, 2, 3단계가 더 많은 것을 볼 수 있습니다. 1단계와 2단계는 새로운 규칙이며 "Undefound"와 "Null"이 값에 속하지 않기 때문에 매우 특별합니다. [[class]] 속성은 엄격 모드와 아무 관련이 없습니다(대부분의 함수에서 이 값은 엄격 모드에서만 정의되지 않거나 null로 유지되며 비표준 모드에서는 자동으로 전역 객체가 됩니다). 3단계는 새로운 규칙이 아닙니다. ES3 엔진에서는 이 단계에서 세 가지 기본 값 유형이 해당 패키징 객체로 변환되지만 ES5에서는 [[Class. ]] 속성에 대해 자세히 설명합니다:
모든 내장 객체의 [[Class]] 속성 값은 이 사양에 의해 정의됩니다. 모든 호스트 객체의 [[Class]] 속성 값은 "Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String" 내부 속성은 엔진이 내부적으로 결정하는 데 사용됩니다. 객체가 속하는 값 유형. 이 사양은 Object.prototype.toString 메소드를 통하는 것 외에는 프로그램이 이 속성의 값에 액세스할 수 있는 다른 방법을 제공하지 않는다는 점에 유의해야 합니다(15.2.4.2 참조).
ES3와 비교했을 때 첫 번째 차이점은 [[class]]에 내부 속성 값이 2개 더 많아 12가지 유형이 된다는 점입니다. 하나는 인수 객체의 [[class]]가 "Arguments"가 되고, 이전 "Object"에는 [[class]] 값이 "JSON"인 전역 개체 JSON이 여러 개 있습니다. 두 번째 차이점은 호스트 개체의 [[class]] 내부 속성 값이 이 12개와 충돌한다는 것입니다. 하지만 ES3를 지원하는 브라우저에서는 이 10개의 값을 의도적으로 사용하는 호스트 개체가 없는 것 같습니다.
ECMAScript 6
ES6는 아직 작업 중인 초안이지만 확실한 것은 [[class]] 내부 속성이 사라지고 다른 내부 속성인 [[NativeBrand]]로 대체되었다는 것입니다. [[NativeBrand]] 속성은 다음과 같이 정의됩니다. :
内部属性 | 属性值 | 描述 |
---|---|---|
[[NativeBrand]] | 枚举NativeBrand的一个成员. | 该属性的值对应一个标志值(tag value),可以用来区分原生对象的类型. |
[[NativeBrand]] 속성 설명:
[[NativeBrand]] 내부 속성은 네이티브 객체가 이 사양을 준수하는 특정 유형의 객체인지 식별하는 데 사용됩니다. 다음 열거 유형 A: NativeFunction, NativeArray, StringWrapper, BooleanWrapper, NumberWrapper, NativeMath, NativeDate, NativeRegExp, NativeError, NativeJSON, NativeArguments, NativePrivateName [[NativeBrand]] 내부 속성은 ECMAScript 네이티브 객체의 특정 유형을 구별하는 데만 사용됩니다. 표 10 명시적으로 지정된 객체 유형에만 [[NativeBrand]] 내부 속성이 있습니다.
표 10 — [[NativeBrand]] 내부 속성 값
属性值 | 对应类型 |
---|---|
네이티브 함수 | 함수 객체 |
네이티브어레이 | 객체 배열 |
문자열 래퍼 | 문자열 객체 |
부울 래퍼 | 부울 객체 |
번호 래퍼 | 숫자 개체 |
네이티브 수학 | 수학 객체 |
NativeDate | 날짜 객체 |
NativeRegExp | RegExp 객체 |
네이티브 오류 | 오류 개체 |
네이티브JSON | JSON 객체 |
네이티브 인수 | 인수 객체 |
NativePrivateName | 개인 이름 개체 |
[[class]]와 달리 모든 객체에 [[NativeBrand]]가 있는 것은 아님을 알 수 있습니다. 동시에 Object.prototype.toString 메서드의 사양도 다음과 같이 변경되었습니다. 🎜>
15.2.4.2 Object.prototype.toString ( )
toString 메소드가 호출되면 다음 단계가 수행됩니다.이 값이 정의되지 않은 경우 "[객체 정의되지 않음]"을 반환합니다.
또는 "String"이면 태그가 문자열 "~"와 태그의 현재 값을 연결한 결과가 되도록 합니다.
표 29 — [[NativeBrand]] 플래그 값
[[네이티브브랜드]] 값 | 플래그 값 |
---|---|
네이티브 함수 | <font face="NSimsun">"Function"</font> |
네이티브어레이 | <font face="NSimsun">"Array"</font> |
문자열 래퍼 | <font face="NSimsun">"String"</font> |
부울 래퍼 | <font face="NSimsun">"Boolean"</font> |
번호 래퍼 | <font face="NSimsun">"Number"</font> |
네이티브 수학 | <font face="NSimsun">"Math"</font> |
NativeDate | <font face="NSimsun">"Date"</font> |
NativeRegExp | <font face="NSimsun">"RegExp"</font> |
네이티브 오류 | <font face="NSimsun">"Error"</font> |
네이티브JSON | <font face="NSimsun">"JSON"</font> |
NativeArguments | <font face="NSimsun">"Arguments"</font> |
可以看到,在规范上有了很大的变化,不过对于普通用户来说,貌似感觉不到.
也许你发现了,ES6里的新类型Map,Set等,都没有在表29中.它们在执行toString方法的时候返回的是什么?
console.log(Object.prototype.toString.call(Map())) //"[object Map]" console.log(Object.prototype.toString.call(Set())) //"[object Set]"
其中的字符串"Map"是怎么来的呢:
15.14.5.13 Map.prototype.@@toStringTag
@@toStringTag 属性的初始值为字符串"Map".
由于ES6的规范还在制定中,各种相关规定都有可能改变,所以如果想了解更多细节.看看下面这两个链接,现在只需要知道的是:[[class]]没了,使用了更复杂的机制.
以上所述是小编给大家分享的JavaScript中Object.prototype.toString方法的原理,希望对大家有所帮助!