일부 리터럴에 대해 instanceof가 false를 반환하는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/203739

  •  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; 

당신은 이것을 사용할 수 있습니다. 두 경우 모두에서 작동합니다.

  1. var text="foo"; // typeof가 작동합니다

  2. 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');

이것들은 모두 참으로 돌아와야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top