Ada beberapa cara berbeda untuk memanggil suatu fungsi tanpa tanda kurung.
Mari kita asumsikan Anda memiliki fungsi ini didefinisikan:
function greet() {
console.log('hello');
}
Kemudian di sini ikuti beberapa cara untuk menelepon greettanpa tanda kurung:
1. Sebagai Pembuat
Dengan newAnda dapat memanggil fungsi tanpa tanda kurung:
new greet; // parentheses are optional in this construct.
Dari MDN pada newoprator :
Sintaksis
new constructor[([arguments])]
2. Sebagai toStringatau valueOfImplementasi
toStringdan valueOfmerupakan metode khusus: mereka dipanggil secara implisit ketika konversi diperlukan:
var obj = {
toString: function() {
return 'hello';
}
}
'' + obj; // concatenation forces cast to string and call to toString.
Anda dapat (ab) menggunakan pola ini untuk memanggil greettanpa tanda kurung:
'' + { toString: greet };
Atau dengan valueOf:
+{ valueOf: greet };
valueOfdan toStringyang sebenarnya disebut dari @@ toPrimitive metode (sejak ES6), dan sehingga Anda juga dapat menerapkan bahwa metode:
+{ [Symbol.toPrimitive]: greet }
"" + { [Symbol.toPrimitive]: greet }
2.b Mengesampingkan valueOfPrototipe Fungsi
Anda dapat mengambil ide sebelumnya untuk mengganti valueOfmetode pada Functionprototipe :
Function.prototype.valueOf = function() {
this.call(this);
// Optional improvement: avoid `NaN` issues when used in expressions.
return 0;
};
Setelah Anda selesai melakukannya, Anda dapat menulis:
+greet;
Dan meskipun ada tanda kurung di telepon, doa pemicu yang sebenarnya tidak memiliki tanda kurung. Lihat lebih lanjut tentang ini di blog "Metode pemanggilan dalam JavaScript, tanpa benar-benar memanggilnya"
3. Sebagai Generator
Anda bisa mendefinisikan fungsi generator (dengan *), yang mengembalikan iterator . Anda dapat memanggilnya menggunakan sintaks spread atau dengan for...ofsintaks.
Pertama kita membutuhkan varian generator dari greetfungsi aslinya :
function* greet_gen() {
console.log('hello');
}
Dan kemudian kita menyebutnya tanpa tanda kurung dengan mendefinisikan metode @@ iterator :
[...{ [Symbol.iterator]: greet_gen }];
Biasanya generator memiliki yieldkata kunci di suatu tempat, tetapi fungsi tersebut tidak diperlukan untuk dipanggil.
Pernyataan terakhir memanggil fungsi, tetapi itu juga bisa dilakukan dengan merusak :
[,] = { [Symbol.iterator]: greet_gen };
atau for ... ofkonstruk, tetapi memiliki tanda kurung sendiri:
for ({} of { [Symbol.iterator]: greet_gen });
Perhatikan bahwa Anda dapat melakukan hal di atas dengan greetfungsi asli juga, tetapi itu akan memicu pengecualian dalam proses, setelah greet dieksekusi (diuji pada FF dan Chrome). Anda dapat mengelola pengecualian dengan try...catchblok.
4. Sebagai Getter
@ jehna1 punya jawaban penuh untuk ini, jadi beri dia pujian. Berikut adalah cara untuk memanggil fungsi kurung-kurang pada lingkup global, menghindari metode yang sudah usang__defineGetter__ . Ini menggunakan Object.definePropertysebagai gantinya.
Kita perlu membuat varian greetfungsi asli untuk ini:
Object.defineProperty(window, 'greet_get', { get: greet });
Lalu:
greet_get;
Ganti windowdengan apa pun objek global Anda.
Anda bisa memanggil greetfungsi asli tanpa meninggalkan jejak pada objek global seperti ini:
Object.defineProperty({}, 'greet', { get: greet }).greet;
Tetapi orang dapat berargumen bahwa kami memiliki tanda kurung di sini (meskipun mereka tidak terlibat dalam doa yang sebenarnya).
5. Sebagai Fungsi Tag
Karena ES6 Anda dapat memanggil fungsi yang melewatinya sebagai templat literal dengan sintaks ini:
greet``;
Lihat "Literal Templat Tagged" .
6. Sebagai Proxy Handler
Sejak ES6, Anda dapat menetapkan proxy :
var proxy = new Proxy({}, { get: greet } );
Dan kemudian membaca nilai properti apa pun akan meminta greet:
proxy._; // even if property not defined, it still triggers greet
Ada banyak variasi dari ini. Satu lagi contoh:
var proxy = new Proxy({}, { has: greet } );
1 in proxy; // triggers greet
7. Sebagai pemeriksa contoh
The instanceofOperator mengeksekusi @@hasInstancemetode pada operan kedua, ketika didefinisikan:
1 instanceof { [Symbol.hasInstance]: greet } // triggers greet