일부 리터럴에 대해 instanceof가 false를 반환하는 이유는 무엇입니까?
-
03-07-2019 - |
문제
"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
// the tests against Object really don't make sense
배열 리터럴과 객체 리터럴이 일치합니다...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
왜 모두 그렇지 않습니까?아니면 왜 다들 안 그래? ~ 아니다?
그렇다면 그들은 무엇의 예입니까?
FF3, IE7, Opera, Chrome에서도 마찬가지입니다.따라서 적어도 일관성이 있습니다.
몇 가지를 놓쳤습니다.
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
해결책
프리미티브는 JavaScript 내에서 생성 된 객체와 다른 종류의 유형입니다. 로부터 모질라 API 문서:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
코드로 원시 유형을 구성하는 방법을 찾을 수 없습니다. 아마도 불가능할 것입니다. 이것이 사람들이 사용하는 이유 일 것입니다 typeof "foo" === "string"
대신에 instanceof
.
이런 것들을 기억하는 쉬운 방법은 "내가 세인하고 배우기 쉬운 것이 무엇인지 궁금합니다"라고 스스로에게 묻는 것입니까? 대답이 무엇이든 JavaScript는 다른 일을합니다.
다른 팁
나는 사용한다:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
JavaScript에서 문자열은 리터럴 또는 객체 일 수 있기 때문입니다.
JavaScript에서는 다음을 제외한 모든 것이 객체입니다(또는 적어도 객체로 취급될 수 있음). 기초 요소 (부울, null, 숫자, 문자열 및 값 undefined
(그리고 ES6의 기호)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
보시다시피 객체, 배열 및 값 null
모두 객체로 간주됩니다(null
존재하지 않는 개체에 대한 참조입니다.)함수는 특별한 유형이기 때문에 구별됩니다. 호출 가능 사물.그러나 그것들은 여전히 객체입니다.
반면에 리터럴은 true
, 0
, ""
그리고 undefined
객체가 아닙니다.이는 JavaScript의 기본 값입니다.그러나 부울, 숫자 및 문자열에도 생성자가 있습니다. Boolean
, Number
그리고 String
추가 기능을 제공하기 위해 각각의 기본 요소를 래핑합니다.
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
기본 값이 Boolean
, Number
그리고 String
생성자는 각각 객체가 됩니다.그만큼 instanceof
연산자는 객체에 대해서만 작동합니다(이것이 반환되는 이유입니다). false
기본 값의 경우):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
보시다시피 둘 다 typeof
그리고 instanceof
값이 부울, 숫자 또는 문자열인지 테스트하기에는 충분하지 않습니다. typeof
원시 부울, 숫자 및 문자열에만 작동합니다.그리고 instanceof
원시 부울, 숫자 및 문자열에는 작동하지 않습니다.
다행히도 이 문제에 대한 간단한 해결책이 있습니다.기본 구현은 toString
(즉.기본적으로 정의된 대로 Object.prototype.toString
) 내부를 반환합니다. [[Class]]
기본 값과 객체 모두의 속성:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
내부 [[Class]]
값의 속성은 값의 속성보다 훨씬 더 유용합니다. typeof
가치.우리는 사용할 수 있습니다 Object.prototype.toString
우리 자신의 (보다 유용한) 버전을 만들기 위해 typeof
연산자는 다음과 같습니다:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
이 기사가 도움이 되었기를 바랍니다.기본 객체와 래핑된 객체의 차이점에 대해 자세히 알아보려면 다음 블로그 게시물을 읽어보세요. 자바스크립트 프리미티브의 비밀스러운 삶
생성자 속성을 사용할 수 있습니다.
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
당신은 이것을 사용할 수 있습니다. 두 경우 모두에서 작동합니다.
var text="foo";
// typeof가 작동합니다String text= new String("foo");
// instanceof가 작동합니다
나는 실행 가능한 해결책을 생각해 냈다고 생각합니다.
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
이것은 ECMAScript 사양에 정의되어 있습니다 섹션 7.3.19 3 단계: If Type(O) is not Object, return false.
다시 말해, 경우 Obj
안에 Obj instanceof Callable
대상이 아닙니다 instanceof
단락이 될 것입니다 false
곧장.
https://www.npmjs.com/package/typeof
문자열 표현을 반환합니다 instanceof
(생성자 이름)
function instanceOf(object) {
var type = typeof object
if (type === 'undefined') {
return 'undefined'
}
if (object) {
type = object.constructor.name
} else if (type === 'object') {
type = Object.prototype.toString.call(object).slice(8, -1)
}
return type.toLowerCase()
}
instanceOf(false) // "boolean"
instanceOf(new Promise(() => {})) // "promise"
instanceOf(null) // "null"
instanceOf(undefined) // "undefined"
instanceOf(1) // "number"
instanceOf(() => {}) // "function"
instanceOf([]) // "array"
나에게 발생한 혼란
"str".__proto__ // #1
=> String
그래서 "str" istanceof String
돌아와야합니다 true
다음과 같이 어떻게 작동 하는가 :
"str".__proto__ == String.prototype // #2
=> true
표현의 결과 #1 그리고 #2 서로 갈등을 겪으므로 그들 중 하나가 잘못되어야합니다.
#1이 잘못되었습니다
나는 그것이 발생한다는 것을 알아 낸다 __proto__
비 표준 속성이므로 표준 속성을 사용하십시오.Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
이제 표현 사이에 혼란이 없습니다 #2 그리고 #3
또는 자신의 기능 만 그렇게 할 수 있습니다.
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
용법:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
이것들은 모두 참으로 돌아와야합니다.