ES6 nesnelerindeki yöntemler: ok işlevlerini kullanma


96

ES6'da bunların ikisi de yasaldır:

var chopper = {
    owner: 'Zed',
    getOwner: function() { return this.owner; }
};

ve kısaca:

var chopper = {
    owner: 'Zed',
    getOwner() { return this.owner; }
}

Yeni ok işlevlerini de kullanmak mümkün mü? Gibi bir şey denerken

var chopper = {
    owner: 'John',
    getOwner: () => { return this.owner; }
};

veya

var chopper = {
    owner: 'John',
    getOwner: () => (this.owner)
};

Yöntemin erişiminin olmadığını gösteren bir hata mesajı alıyorum this. Bu sadece bir sözdizimi sorunu mu yoksa ES6 nesnelerinin içinde yağ borusu yöntemlerini kullanamaz mısınız?


11
Yeni işlev sözdiziminin en büyük noktalarından biri, thisfarklı şekilde davranmasıydı . İşlevin oluşturulduğu sözcüksel ortam tarafından tanımlanır, bu this, chopperdeğişkeni yarattığınız thisdeğerin işlevin değeri olacağı anlamına gelir . Başka bir deyişle, choppernesneye atıfta bulunmayacaktır .

1
Şişman ok sözdizimini kullanırken? Yalnızca thisdeğeri önce choppernesneyi oluşturarak değiştirirseniz , ardından atamayı thiso nesneye işaret eden bir işlevde gerçekleştirirseniz . Bu, bir yapıcı işlevi ile oldukça temiz bir şekilde gerçekleştirilebilir.

1
Bu demo Firefox'ta çalışacak. Chrome'da henüz yok. jsfiddle.net/bfyarxfe

2
@fox, o jsfiddle'da 'sıkı kullan' kullanmalısınız.
Walter Chapilliquen - wZVanG

1
@fox: Desteklenen bir ortamda sorunsuz çalışıyor. Firefox henüz tam desteğe sahip değil. İçinde Deneyin Devamlılıkta ve console.log()yöntem çağrısı sonucu. İşe yarıyor.

Yanıtlar:


154

Ok işlevleri, her durumda yalnızca eski moda işlevlerin daha kısa bir versiyonu olarak kullanılmak üzere tasarlanmamıştır. functionAnahtar kelimeyi kullanarak işlev sözdizimini değiştirmeleri amaçlanmamıştır . Ok işlevlerinin en yaygın kullanım durumu, yeniden tanımlamayan kısa "lambdalar" dır ve thisgenellikle bir işlevi bazı işleve geri çağrı olarak iletirken kullanılır.

Ok fonksiyonları nesne yöntemlerini yazmak için kullanılamaz, çünkü bulduğunuz gibi, ok işlevleri thissözcüksel olarak çevreleyen bağlamın üzerine yakın olduğundan, ok thisiçindeki, nesneyi tanımladığınız yerde geçerli olandır. Söylenmek istenen:

// Whatever `this` is here...
var chopper = {
    owner: 'Zed',
    getOwner: () => {
        return this.owner;    // ...is what `this` is here.
    }
};

Sizin durumunuzda, bir nesneye bir yöntem yazmak istiyorsanız, yalnızca geleneksel functionsözdizimini veya ES6'da tanıtılan yöntem sözdizimini kullanmalısınız:

var chopper = {
    owner: 'Zed',
    getOwner: function() {
        return this.owner;
    }
};

// or

var chopper = {
    owner: 'Zed',
    getOwner() {
        return this.owner;
    }
};

(Aralarında küçük farklar vardır, ancak bunlar yalnızca superiçinde kullanırsanız getOwner, kullanmıyorsanız veya getOwnerbaşka bir nesneye kopyalarsanız önemlidir .)

Es6 posta listesinde, benzer sözdizimine sahip ancak kendilerine ait olan ok işlevlerinde bir bükülme hakkında bazı tartışmalar vardı this. Bununla birlikte, bu öneri zayıf bir şekilde alındı ​​çünkü bu sadece sözdizimi şekeri, insanların birkaç karakter yazarak kaydetmelerine izin veriyor ve mevcut işlev sözdizimi üzerinde yeni işlevler sağlamıyor. Sınırsız ok işlevleri konusuna bakın .


Bunu doğru okursam, posta listesinin, kodun daha fazla tekdüzeliğine / okunabilirliğine yol açacak olsa bile, sözdizimsel şekeri önemsizleştirdiğini gösteriyor gibi görünüyor. Hali hazırda, şişman ok işlevlerini ES6 altında bir OOP bağlamında kullanmak, örneğin kahve kağıdına göre çok daha zordur.
tilki

Anladığım kadarıyla, sözdizimsel şeker olan dil uzantıları dikkate için geçerli bir sebep olarak kabul ama daha düşük öncelikli söylediği gibi - başka bir deyişle, çubuk böyle teklif yüksektir.

12

Bu satırda getOwner: => (this.owner)şunlar olmalıdır:

var chopper = {
    owner: 'John',
    getOwner: () => this.owner
}; //here `this` refers to `window` object.

thisBir işleve şunları bildirmeniz gerekir :

var chopper = {
    owner: 'John',
    getOwner() { return this.owner }
};

Veya:

var chopperFn = function(){

    this.setOwner = (name) => this.owner = name;
    Object.assign(this,{
        owner: 'Jhon',
        getOwner: () => this.owner,
    })

}

var chopper = new chopperFn();
console.log(chopper.getOwner());
chopper.setOwner('Spiderman');
console.log(chopper.getOwner());


1
Burada bir hata alıyorum:"TypeError: Cannot read property 'owner' of undefined\n at Object.chopper.getOwner
fox

Anlıyorum, doğru kullanım bu, ancak esta yöntemi her zaman pencere Object'i döndürüyor. thisBir işlev içinde bildirmeniz gerekir .
Walter Chapilliquen - wZVanG

2
thismutlaka başvurmaz window. thisÇevreleyen ortamdaki mevcut değer ne olursa olsun, olabilir veya olmayabilir window. Belki de demek istediğin budur. Sadece bunun varsayılan bir değer olmadığını anladığından emin olmak istiyorum.

@torazaburo Bu benim için iyi, denedim, thisşimdi sınıfa atıfta bulunuyor
Walter Chapilliquen - wZVanG

2
Yazdıkların eşdeğerdir, ancak sadece yazmaktan daha ayrıntılıdır var chopperFn = function() { this.owner = 'Jhon'; this.getOwner = () => this.owner; }.

1

Ok işlevlerini kullanmak için takip ettiğim hızlı bir ipucu.

  • object.method()Sözdizimi kullanacak yöntemler için ok içermeyen işlevleri kullanın. (Bunlar, thisarayan kişiden anlamlı değer alacak işlevlerdir .)
  • Hemen hemen her şey için ok işlevini kullanın.


0

Eğer kullanım ok işlevine varsa, değiştirebilir thisiçin chopper,

var chopper = {
  owner: "John",
  getOwner: () => chopper.owner
};

Bu en iyi uygulama olmasa da, nesne adını değiştirdiğinizde bu ok işlevini değiştirmeniz gerekir.


0

Katı modda başka bir ipucu, thistanımsız yerine Pencereye atıfta bulunur.

  (() => {
    "use strict";
    console.log(this); // window
  })();

  (function () {
    "use strict";
    console.log(this); // undefined
  })();
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.