괄호없이 함수를 호출하는 방법에는 여러 가지가 있습니다.
이 함수를 정의했다고 가정 해 봅시다.
function greet() {
console.log('hello');
}
그런 다음 greet
괄호없이 호출하는 몇 가지 방법을 따르십시오 .
1. 생성자로서
함께 new
사용하면 함수를 괄호없이 호출 할 수 있습니다 :
new greet; // parentheses are optional in this construct.
에서 온 MDN new
oprator :
통사론
new constructor[([arguments])]
2. 그대로 toString
또는 valueOf
구현
toString
그리고 valueOf
특별한 방법은 다음과 같습니다 변환이 필요한 경우가 암시 적으로 호출되는 :
var obj = {
toString: function() {
return 'hello';
}
}
'' + obj; // concatenation forces cast to string and call to toString.
이 패턴을 사용하여 greet
괄호없이 호출 할 수 있습니다.
'' + { toString: greet };
또는과 valueOf
:
+{ valueOf: greet };
valueOf
그리고 toString
실제로에서 호출 @@ toPrimitive (ES6부터) 방법, 그래서 당신은 또한 구현할 수 있습니다 그 방법을 :
+{ [Symbol.toPrimitive]: greet }
"" + { [Symbol.toPrimitive]: greet }
2.b valueOf
함수 프로토 타입에서 재정의
프로토 타입 에서 valueOf
메소드 를 대체하기 위해 이전 아이디어를 취할 수 있습니다 .Function
Function.prototype.valueOf = function() {
this.call(this);
// Optional improvement: avoid `NaN` issues when used in expressions.
return 0;
};
일단 그렇게하면 다음과 같이 쓸 수 있습니다.
+greet;
그리고 줄 아래에 괄호가 있지만 실제 트리거 호출에는 괄호가 없습니다. "실제로 호출하지 않고 JavaScript에서 메소드 호출" 블로그에서 이에 대해 자세히 알아보십시오.
3. 발전기로
iterator 를 반환하는 생성기 함수 (로 *
)를 정의 할 수 있습니다. 스프레드 구문 이나 구문을 사용하여 호출 할 수 있습니다 .for...of
먼저 원래 greet
함수 의 생성기 변형이 필요 합니다.
function* greet_gen() {
console.log('hello');
}
그리고 @@ iterator 메소드를 정의하여 괄호없이 호출합니다 .
[...{ [Symbol.iterator]: greet_gen }];
일반적으로 생성기는 yield
어딘가에 키워드를 갖지만 함수를 호출 할 필요는 없습니다.
마지막 문장은 함수를 호출하지만, 그것은 파괴로 도 가능합니다 :
[,] = { [Symbol.iterator]: greet_gen };
또는 for ... of
구문이지만 자체 괄호가 있습니다.
for ({} of { [Symbol.iterator]: greet_gen });
원래 기능을 사용하여 위의 작업을 수행 할 수도greet
있지만 실행 후 greet
(FF 및 Chrome에서 테스트 된) 프로세스에서 예외가 발생합니다 . try...catch
블록으로 예외를 관리 할 수 있습니다.
4. 게터로서
@ jehna1은 이것에 대한 완전한 답을 가지고 있으므로 그에게 신용을주십시오. 다음은 사용되지 않는 메소드를 피하면서 전역 범위에서 괄호 없이 함수를 호출하는 방법입니다. 대신 사용 합니다.__defineGetter__
Object.defineProperty
이를 위해 원래 greet
함수 의 변형을 작성해야합니다 .
Object.defineProperty(window, 'greet_get', { get: greet });
그리고:
greet_get;
교체 window
글로벌 객체가 무엇이든 함께.
다음 greet
과 같이 전역 객체에 흔적을 남기지 않고 원래 함수를 호출 할 수 있습니다 .
Object.defineProperty({}, 'greet', { get: greet }).greet;
그러나 우리는 여기에 괄호가 있다고 주장 할 수 있습니다 (실제 호출에 관여하지는 않지만).
5. 태그 기능
ES6부터 다음 구문 으로 템플릿 리터럴 을 전달하는 함수를 호출 할 수 있습니다 .
greet``;
"태그 된 템플릿 리터럴"을 참조하십시오 .
6. 프록시 처리기
ES6부터 프록시를 정의 할 수 있습니다 .
var proxy = new Proxy({}, { get: greet } );
그런 다음 속성 값을 읽으면 다음이 호출됩니다 greet
.
proxy._; // even if property not defined, it still triggers greet
이것에는 많은 변형이 있습니다. 하나 더 예 :
var proxy = new Proxy({}, { has: greet } );
1 in proxy; // triggers greet
7. 인스턴스 검사기
instanceof
연산자는 실행 @@hasInstance
정의 할 때 두 번째 오퍼랜드에 대한 방법 :
1 instanceof { [Symbol.hasInstance]: greet } // triggers greet