JavaScript에서 특정 함수 호출을 "불법 호출"이라고하는 이유는 무엇입니까?


96

예를 들어 이렇게하면 :

var q = document.querySelectorAll;

q('body');

Chrome에서 '잘못된 호출'오류가 발생합니다. 왜 이것이 필요한지 생각할 수 없습니다. 하나의 경우 모든 네이티브 코드 기능이있는 것은 아닙니다. 사실 나는 이것을 할 수있다 :

var o = Object; // which is a native code function

var x = new o();

그리고 모든 것이 잘 작동합니다. 특히 문서와 콘솔을 다룰 때이 문제를 발견했습니다. 이견있는 사람?




답변:


157

함수의 "컨텍스트"를 잃어 버렸기 때문입니다.

전화 할 때 :

document.querySelectorAll()

함수의 컨텍스트는 이며 해당 메서드를 구현하여 document액세스 할 수 있습니다 this.

그냥 호출하면 q더 이상 컨텍스트가 없습니다 window. 대신 "전역" 객체입니다.

구현은 querySelectorAll사용 을 시도 this하지만 더 이상 DOM 요소가 아니라 Window객체입니다. 구현은 Window객체에 존재하지 않는 DOM 요소의 일부 메서드를 호출하려고 시도 하고 인터프리터는 당연히 파울을 호출합니다.

이 문제를 해결하려면 .bind최신 버전의 Javascript를 사용하십시오.

var q = document.querySelectorAll.bind(document);

모든 후속 호출이 q올바른 컨텍스트 를 갖도록합니다. 없는 경우 다음을 .bind사용하십시오.

function q() {
    return document.querySelectorAll.apply(document, arguments);
}

3
오, 좋은 전화입니다. 내가 할 수 있기 때문에 당신 말이 맞습니다 : q.apply (document, [ 'body']); 그리고 그것은 작동합니다.
user1152187

이것은 IE의 내장 함수에 대한 작업이 필요하지 않습니다. 예를 들어, console.log에는 적용 방법이 없습니다.
hugomg

@Alnitak : 네, IE를 제외한 모든 곳에서 작동하며 function q(x){ return document.querySelectorAll(x); }. IE 브라우저 객체에 대해 정말 좋아하는 또 다른 점은 속성을 읽으려고 할 때 예외가 발생하기 때문에 if( 'funcname' in browserobject)평소 대신 기능을 테스트해야한다는 것입니다 if(browserobject.funcname)!
hugomg

훌륭한 대답, 나는 OP와 똑같은 상황 인이 현상으로 정말로 혼란 스러웠습니다.
temporary_user_name

1
마음을 날려. 감사합니다.
rb-

1

제 경우에는 선언되지 않은 변수를 인수로 사용하여 잘못된 호출이 발생했습니다. 함수에 전달하기 전에 변수를 선언해야합니다.


당신이 순간 Q = document.something 때문에 불법의 호출이 특별한 경우에 이해가되지 않습니다 선언 변수가 DOM 의존하는 방법으로 일어나고은, DOM의 문맥 호출되는 something방법 것은 문서의 맥락을 푼다
Anshul Sahni


0

한 가지 더 간결한 해결책 :

const q=s=>document.querySelectorAll(s);
q('body');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.