Teklife göre , oklar "geleneksel olan birkaç ortak ağrı noktasına hitap etmek ve çözmek Function Expression
". Bunlar this
sözcüksel olarak bağlanarak ve kısa sözdizimi sunarak konuları iyileştirmeyi amaçladılar .
Ancak,
- Kişi sürekli
this
olarak sözcük olarak bağlanamaz
- Ok işlevi sözdizimi hassas ve belirsiz
Bu nedenle, ok işlevleri karışıklık ve hatalar için fırsatlar yaratır ve bir JavaScript programcısının kelime haznesinin dışında bırakılmalıdır. function
.
Sözlük ile ilgili this
this
sorunlu:
function Book(settings) {
this.settings = settings;
this.pages = this.createPages();
}
Book.prototype.render = function () {
this.pages.forEach(function (page) {
page.draw(this.settings);
}, this);
};
Ok işlevleri this
, geri arama içindeki bir özelliğe erişmemiz gereken sorunu gidermeyi amaçlamaktadır . Bunu yapmanın zaten birkaç yolu vardır: Bir this
değişkene atanabilir bind
, Array
toplama yöntemlerinde kullanılabilen 3. bağımsız değişkeni kullanabilir veya kullanabilirsiniz . Yine de oklar en basit çözüm gibi görünmektedir, bu nedenle yöntem şu şekilde yeniden düzenlenebilir:
this.pages.forEach(page => page.draw(this.settings));
Ancak, kodun yöntemleri this
özel olarak bağlanan jQuery gibi bir kitaplık kullanıp kullanmadığını göz önünde bulundurun . Şimdi, this
ele alınması gereken iki değer var:
Book.prototype.render = function () {
var book = this;
this.$pages.each(function (index) {
var $page = $(this);
book.draw(book.currentPage + index, $page);
});
};
Biz kullanmalıdır function
için sıraylaeach
this
Dinamik olarak bağlamak . Burada bir ok işlevi kullanamayız.
Birden fazla this
değerle uğraşmak da kafa karıştırıcı olabilir, çünkü this
bir yazarın hangi konu hakkında konuştuğunu bilmek zordur :
function Reader() {
this.book.on('change', function () {
this.reformat();
});
}
Yazar gerçekten aramak istiyor muydu Book.prototype.reformat
? Yoksa bağlanmayı this
ve aramayı planladı Reader.prototype.reformat
mı? İşleyiciyi bir ok işlevine değiştirirsek, benzer şekilde yazarın dinamiği isteyip istemediğini merak eder this
, ancak bir satıra sığdığı için bir ok seçer:
function Reader() {
this.book.on('change', () => this.reformat());
}
Birisi şu şekilde olabilir: "Okların bazen yanlış bir işlev olması istisnai olabilir mi? Belki de nadiren dinamik this
değerlere ihtiyacımız olursa , çoğu zaman okları kullanmakta sorun olmaz."
Ama kendinize şunu sorun: "Kod hatalarını ayıklamak ve bir hatanın sonucunun bir 'son durum tarafından getirildiğini bulmak' buna değer mi? '" Zamanın% 100'ü.
Daha iyi bir yol var: Her zaman kullanın function
(böylece this
her zaman dinamik olarak bağlanabilir) ve her zaman this
bir değişken aracılığıyla referans alın . Değişkenler sözcükseldir ve birçok isim varsayarlar. this
Bir değişkene atamak niyetlerinizi netleştirecektir:
function Reader() {
var reader = this;
reader.book.on('change', function () {
var book = this;
book.reformat();
reader.reformat();
});
}
Ayrıca, her zamanthis
bir değişkene atamak (tek bir this
fonksiyon olsa bile veya başka bir fonksiyon olmasa bile) kod değiştirildikten sonra bile niyetlerinin net kalmasını sağlar.
Ayrıca, dinamik this
neredeyse istisnai değildir. jQuery 50 milyondan fazla web sitesinde kullanılmaktadır (Şubat 2016'da bu yazıdan itibaren). this
Dinamik olarak bağlanan diğer API'lar şunlardır :
- Mocha (~ 120 bin indirme) dün için test metotları ortaya koyuyor
this
.
- Grunt (~ 63k indirme dün) üzerinden görevleri oluşturmak için yöntemler ortaya koymaktadır
this
.
- Omurga (dün ~ 22 bin indirme) erişim yöntemlerini tanımlar
this
.
- Etkinlik API'ları (DOM'lar gibi) bir
EventTarget
ile ilgilidir this
.
- Yamalı veya uzatılmış prototip API'leri, ile olan örnekleri ifade eder
this
.
( Http://trends.builtwith.com/javascript/jQuery ve https://www.npmjs.com üzerinden istatistikler .)
this
Zaten dinamik bağlamalar gerektiriyor olabilirsiniz .
Sözcük bilgisi this
bazen beklenir, bazen beklemez ; tıpkı bir dinamik this
beklendiği gibi bazen de beklenmiyor. Neyse ki, her zaman beklenen bağlamayı üreten ve ileten daha iyi bir yol var.
Kısa sözdizimi ile ilgili
Ok işlevleri, işlevler için "daha kısa sözdizimsel form" sağlamada başarılı olmuştur. Ancak bu daha kısa fonksiyonlar sizi daha başarılı kılacak mı?
Mı x => x * x
daha "kolay okunur" function (x) { return x * x; }
? Belki de öyle, çünkü tek, kısa bir kod satırı üretme olasılığı daha yüksektir. Dyson'a göre Okuma hızı ve satır uzunluğunun ekrandan okumanın etkinliği üzerindeki etkisi ,
Normal ve yüksek hızlarda etkili okumayı desteklemek için orta satır uzunluğu (satır başına 55 karakter) görünür. Bu, en yüksek düzeyde kavrayışı sağlamıştır. . .
Koşullu (üçlü) operatör ve tek satırlı if
ifadeler için benzer gerekçeler yapılır .
Ancak, teklifte tanıtılan basit matematiksel fonksiyonları gerçekten yazıyor musunuz? Etki alanlarım matematiksel değil, bu yüzden altyordamlarım nadiren çok zarif. Aksine, ok işlevlerinin bir sütun sınırını kırdığını ve Dyson'un tanımına göre "okunabilirliği" geçersiz kılan editör veya stil kılavuzu nedeniyle başka bir satıra sarıyorum.
"Mümkün olduğunda kısa fonksiyonlar için kısa versiyonu kullanmaya ne dersiniz?" Ancak şimdi stilistik bir kural, bir dil kısıtlamasıyla çelişmektedir: "Bazen yalnızca en uzun gösterimin this
beklendiği gibi bağlanacağını aklınızda tutarak, mümkün olan en kısa işlev gösterimini kullanmaya çalışın ." Bu tür bir birleşim okları özellikle yanlış kullanıma eğilimli hale getirir.
Ok işlevi sözdiziminde çok sayıda sorun var:
const a = x =>
doSomething(x);
const b = x =>
doSomething(x);
doSomethingElse(x);
Bu işlevlerin her ikisi de sözdizimsel olarak geçerlidir. Ancak doSomethingElse(x);
, b
sadece zayıf girintili, üst düzey bir ifadedir.
Blok formuna genişletilirken, artık return
geri yüklenmeyi unutabilecek bir örtük yoktur . Ancak ifadenin yalnızca bir yan etki yaratması amaçlanmış olabilir , bu yüzden return
ileride açık bir ifadenin gerekli olup olmayacağını kim bilebilir ?
const create = () => User.create();
const create = () => {
let user;
User.create().then(result => {
user = result;
return sendEmail();
}).then(() => user);
};
const create = () => {
let user;
return User.create().then(result => {
user = result;
return sendEmail();
}).then(() => user);
};
Dinlenme parametresi olarak düşünülmesi gerekenler, yayma işleci olarak ayrıştırılabilir:
processData(data, ...results => {}) // Spread
processData(data, (...results) => {}) // Rest
Atama varsayılan bağımsız değişkenlerle karıştırılabilir:
const a = 1;
let x;
const b = x => {}; // No default
const b = x = a => {}; // "Adding a default" instead creates a double assignment
const b = (x = a) => {}; // Remember to add parens
Bloklar nesneler gibi görünür:
(id) => id // Returns `id`
(id) => {name: id} // Returns `undefined` (it's a labeled statement)
(id) => ({name: id}) // Returns an object
Ne anlama geliyor?
() => {}
Yazar boş bir nesne veya boş bir nesne döndüren bir işlev mi yaratmayı planladı? (Bunu göz önünde bulundurarak, daha {
sonra yerleştirmeliyiz =>
mi? Kendimizi yalnızca ifade sözdizimiyle sınırlamalı mıyız? Bu, okların sıklığını daha da azaltacaktır.)
=>
şöyle görünür <=
ve >=
:
x => 1 ? 2 : 3
x <= 1 ? 2 : 3
if (x => 1) {}
if (x >= 1) {}
Bir ok işlevi ifadesini hemen çağırmak için, kişinin ()
dışarıya yerleştirilmesi gerekir , ancak ()
içeriye yerleştirmek geçerlidir ve kasıtlı olabilir.
(() => doSomething()()) // Creates function calling value of `doSomething()`
(() => doSomething())() // Calls the arrow function
Her ne kadar, kişi (() => doSomething()());
hemen çağrılmış bir işlev ifadesi yazmak niyetiyle yazarsa, hiçbir şey olmayacaktır.
Yukarıdaki tüm durumlar göz önünde bulundurularak ok işlevlerinin "daha anlaşılır" olduğunu iddia etmek zor. Bir olabilirdi bu sözdizimini kullanmak için gerekli tüm özel kuralları öğrenirler. Gerçekten buna değer mi?
Sözdizimi function
alışılmadık şekilde genelleştirilmiştir. Özel olarak kullanmak function
, dilin kendisinin kafa karıştırıcı kod yazmasını engellediği anlamına gelir. Her durumda sözdizimsel olarak anlaşılması gereken prosedürleri yazmak için seçiyorum function
.
Kılavuz hakkında
"Açık" ve "tutarlı" olması gereken bir yönerge istersiniz. Ok işlevlerinin kullanılması sonuçta sözdizimsel olarak geçerli, mantıksal olarak geçersiz bir kodla sonuçlanır ve her iki işlev formu da anlamlı ve isteğe bağlı olarak iç içe geçer. Bu nedenle, aşağıdakileri sunuyoruz:
ES6'daki İşlev Gösterimi için Kılavuz:
- Her zaman ile prosedürler oluşturun
function
.
- Her zaman
this
bir değişkene atayın . Kullanmayın () => {}
.
Fixed this bound to scope at initialisation
Bir sınırlama olarak mı düşünüyorsunuz ?