Javascript 클래스가 다른 클래스를 상속하는지 확인하는 방법 (obj를 생성하지 않고)?


79

예 :

function A(){}
function B(){}
B.prototype = new A();

클래스 B가 클래스 A를 상속하는지 어떻게 확인할 수 있습니까?

답변:


142

다음을 시도하십시오.

ChildClass.prototype instanceof ParentClass

6
무엇에 대한 ES6 class ? class A extends B{}그런 다음 클래스의 상속을 어떻게 확인할 수 A
Omid

5
@Omid ES6 클래스 구문 은 대부분 특수 구문 입니다. 이면에서 "클래스"의 실제 처리는 변경되지 않았으므로 계속 작업 할 수 있습니다 A.prototype. ... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Thomas Urban

31

직접 상속을 테스트 할 수 있습니다.

B.prototype.constructor === A

간접 상속을 테스트하려면 다음을 사용할 수 있습니다.

B.prototype instanceof A

(이 두 번째 솔루션은 Nirvana Tikku가 처음 제공했습니다)


6
아니요, 모든 유산 체인이 아닌 상위 클래스 만 확인합니다.
Simon

방금 복원했습니다. (이 대답을 업데이트, 너무) 감사 dystroy
너바나 Tikku

22

2017 년으로 돌아 가기 :
그것이 당신에게 효과가 있는지 확인하십시오

ParentClass.isPrototypeOf(ChildClass)

완벽하게 작동하지만 보푸라기가 불평합니다. 프로그램이 ParentClass를 완전히 제어하지 못하면 ParentClass가 답을 속일 위험이있는 것 같습니다. 모든 프로토 타입 기능으로 확장됩니다. 프로그램이 ParentClass를 완전히 제어 할 수 있다면 문제가되지 않습니다.
Craig Hicks

어떻게 답을 속일 수 있습니까? 기호를 사용하여? 이 디자인에 의해 아마 일어나는 경우 왜 그들은 그렇게해야
pery을 미몬

"또한 개체는 Object.prototype의 내장 기능을 숨기는 속성을 가질 수 있으며, 잠재적으로 의도하지 않은 동작이나 서비스 거부 보안 취약성을 유발할 수 있습니다."
Craig Hicks

"예를 들어, 웹 서버가 클라이언트의 JSON 입력을 구문 분석하고 결과 객체에서 직접 hasOwnProperty를 호출하는 것은 안전하지 않습니다. 악성 클라이언트가 {"hasOwnProperty ": 1}와 같은 JSON 값을 전송하고 서버가 충돌을 일으킬 수 있기 때문입니다. . 이와 같은 미묘한 버그를 방지하려면 항상 Object.prototype에서 이러한 메서드를 호출하는 것이 좋습니다. 예를 들어 foo.hasOwnProperty ( "bar")는 Object.prototype.hasOwnProperty.call (foo, "bar")로 대체해야합니다. " - eslint.org/docs/rules/no-prototype-builtins
크레이그 힉스

나는 그것이 항상 교체되어야한다는 것에 동의하지 않습니다. 이 경우 프로그래머가 가능한 ParentClass 값의 범위를 제어하지 않는 경우에만 필요합니다.
Craig Hicks

1

개는 : 참고 instanceof여러 실행 컨텍스트 / 창을 사용하는 경우 예상대로되지 작업을 수행합니다. §§을 참조하십시오 .


또한 https://johnresig.com/blog/objectgetprototypeof/에 따라 다음과 동일한 대체 구현입니다 instanceof.

function f(_, C) { // instanceof Polyfill
  while (_ != null) {
    if (_ == C.prototype)
      return true;
    _ = _.__proto__;
  }
  return false;
}

클래스를 직접 확인하도록 수정하면 다음과 같은 이점이 있습니다.

function f(ChildClass, ParentClass) {
  _ = ChildClass.prototype;
  while (_ != null) {
    if (_ == C.prototype)
      return true;
    _ = _.__proto__;
  }
  return false;
}


사이드 노트

instanceof경우에 자체 검사 obj.proto이고 f.prototype, 따라서 :

function A(){};
A.prototype = Array.prototype;
[]instanceof Array // true

과:

function A(){}
_ = new A();
// then change prototype:
A.prototype = [];
/*false:*/ _ instanceof A
// then change back:
A.prototype = _.__proto__
_ instanceof A //true

과:

function A(){}; function B(){};
B.prototype=Object.prototype;
/*true:*/ new A()instanceof B 

같지 않으면 proto는 수표에서 proto의 proto로 바뀐 ​​다음 proto의 proto로 바뀝니다. 그러므로:

function A(){}; _ = new A()
_.__proto__.__proto__ = Array.prototype
g instanceof Array //true

과:

function A(){}
A.prototype.__proto__ = Array.prototype
g instanceof Array //true

과:

f=()=>{};
f.prototype=Element.prototype
document.documentElement instanceof f //true
document.documentElement.__proto__.__proto__=[];
document.documentElement instanceof f //false


수정 된 코드 스 니펫에는 'C.prototype'이 있지만 'C'매개 변수를 'ParentClass'로 대체
했습니까

1

나는 Simon B.prototype = new A()이 그의 질문에서 의미하지 않았다고 생각합니다. 이것은 확실히 JavaScript에서 프로토 타입을 연결하는 방법이 아니기 때문입니다.

B가 A를 확장한다고 가정하면 Object.prototype.isPrototypeOf.call(A.prototype, B.prototype)

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