Parantezsiz bir işlevi çağırmanın birkaç farklı yolu vardır.
Bu işlevin tanımlanmış olduğunu varsayalım:
function greet() {
console.log('hello');
}
Ardından greet, parantez olmadan arama yapmanın bazı yollarını izleyin :
1. Yapıcı Olarak
İle newparantez olmadan bir işlevi çağırabilirsiniz:
new greet; // parentheses are optional in this construct.
Gönderen üzerine MDN'yi newoprator :
Sözdizimi
new constructor[([arguments])]
2. Olarak toStringveya valueOfUygulama
toStringve valueOfözel yöntemlerdir: bir dönüşüm gerektiğinde dolaylı olarak çağrılırlar:
var obj = {
toString: function() {
return 'hello';
}
}
'' + obj; // concatenation forces cast to string and call to toString.
greetParantez olmadan aramak için bu deseni kullanabilirsiniz (ab) :
'' + { toString: greet };
Veya valueOf:
+{ valueOf: greet };
valueOfve toStringaslında çağrılan @@ toPrimitive (ES6 beri) yöntemiyle, ve böylece de uygulayabilirsiniz olduğunu yöntemi :
+{ [Symbol.toPrimitive]: greet }
"" + { [Symbol.toPrimitive]: greet }
2.b Geçersiz Kılma valueOf İşlev Prototipinde
PrototipvalueOf üzerindeki yöntemi geçersiz kılmak için önceki fikri kullanabilirsiniz :Function
Function.prototype.valueOf = function() {
this.call(this);
// Optional improvement: avoid `NaN` issues when used in expressions.
return 0;
};
Bunu yaptıktan sonra şunları yazabilirsiniz:
+greet;
Ve çizgide yer alan parantezler olmasına rağmen, gerçek tetikleme çağrısının parantezleri yoktur. Bununla ilgili daha fazla bilgiyi "Gerçekten çağırmadan JavaScript'te arama yöntemleri" başlıklı blogda bulabilirsiniz.
3. Jeneratör Olarak
Yineleyici döndüren bir üreteç işlevi (ile *) tanımlayabilirsiniz . Forma sözdizimini kullanarak veyafor...of .
İlk önce orijinal greetfonksiyonun bir jeneratör varyantına ihtiyacımız var :
function* greet_gen() {
console.log('hello');
}
Ve sonra @@ iterator yöntemini tanımlayarak parantez olmadan çağırıyoruz :
[...{ [Symbol.iterator]: greet_gen }];
Normalde jeneratörler yield yerde anahtar kelimesi , ancak işlevin çağrılması gerekmez.
Son ifade işlevi çağırır, ancak bu yıkımla da yapılabilir :
[,] = { [Symbol.iterator]: greet_gen };
veya bir for ... ofyapı, ancak kendi parantezleri vardır:
for ({} of { [Symbol.iterator]: greet_gen });
Yukarıdakileri orijinal işlevle de yapabileceğinizi unutmayın greet, ancak yürütüldükten sonra işlemde bir istisna tetikleyecektir greet(FF ve Chrome'da test edilmiştir). İstisna birtry...catch blokla .
4. Getter olarak
@ jehna1 bu konuda tam bir cevabı var, bu yüzden ona kredi verin. Aşağıda, kullanım dışı yöntemden kaçınarak, genel kapsamda işlev parantezlerini çağırmanın bir yolu vardır . Bunun yerine kullanır .__defineGetter__Object.defineProperty
Bunun için orijinal greetfonksiyonun bir varyantını oluşturmamız gerekiyor :
Object.defineProperty(window, 'greet_get', { get: greet });
Ve sonra:
greet_get;
windowGlobal nesneniz ne olursa olsun değiştirin .
Orijinal greetnesneye böyle bir iz bırakmadan orijinal işlevi çağırabilirsiniz :
Object.defineProperty({}, 'greet', { get: greet }).greet;
Ancak burada parantezlerimiz olduğu iddia edilebilir (gerçek çağrıyla uğraşmasalar da).
5. Etiket Fonksiyonu Olarak
ES6'dan beri , bu sözdizimiyle bir şablon değişmezi ileten bir işlevi çağırabilirsiniz :
greet``;
Bkz. "Etiketli Şablon Değişmezleri" .
6. Proxy İşleyicisi Olarak
ES6'dan beri bir proxy tanımlayabilirsiniz :
var proxy = new Proxy({}, { get: greet } );
Ve sonra herhangi bir özellik değerini okumak greet:
proxy._; // even if property not defined, it still triggers greet
Bunun birçok varyasyonu var. Bir örnek daha:
var proxy = new Proxy({}, { has: greet } );
1 in proxy; // triggers greet
7. Örnek denetleyicisi olarak
instanceofOperatör yürütür @@hasInstancetanımlandığı zaman ikinci işlenen hakkında bir yöntem:
1 instanceof { [Symbol.hasInstance]: greet } // triggers greet