ES6 sınıfı değişken alternatifleri


492

Şu anda ES5'te birçoğumuz sınıfları ve sınıf değişkenlerini oluşturmak için çerçevelerde aşağıdaki kalıbı kullanıyoruz, ki bu rahat:

// ES 5
FrameWork.Class({

    variable: 'string',
    variable2: true,

    init: function(){

    },

    addItem: function(){

    }

});

ES6'da yerel olarak sınıflar oluşturabilirsiniz, ancak sınıf değişkenlerine sahip olma seçeneği yoktur:

// ES6
class MyClass {
    const MY_CONST = 'string'; // <-- this is not possible in ES6
    constructor(){
        this.MY_CONST;
    }
}

Ne yazık ki, sınıflar sadece yöntemler içerebileceğinden yukarıdakiler işe yaramaz.

Anlıyorum That I Can this.myVar = trueiçindeconstructor ... ama ben daha büyük sınıf için 20-30 + params var, özellikle 'önemsiz' benim yapıcısı, istemiyoruz.

Bu konuyu ele almanın birçok yolunu düşünüyordum, ancak henüz iyi bir şey bulamadım. (Örneğin: bir ClassConfigişleyici oluşturun parameterve sınıftan ayrı olarak bildirilen bir nesneyi iletin. Daha sonra işleyici sınıfa iliştirilir. DüşünüyordumWeakMaps şekilde entegre etmeyi de .)

Bu durumla başa çıkmak için ne tür fikirleriniz olurdu?


1
asıl sorun this.member = member20-30 parametre ile yapıcı bir tekrar olacak olmasıdır ?
Θεόφιλος Μουρατίδης

1
Sadece public variable2 = truesınıfın altında kullanamaz mısın? Bu onu prototip üzerinde tanımlar.

14
@ Θεόφιλος Μουρατίδης: Evet, ayrıca yapıcımı değişken prosedürler için değil başlatma işlemleri için kullanmak istiyorum.
wintercounter

@derylius: Ana sorun bu, böyle bir özelliği yok. Kamusal / özel kullanıma bile ES6 taslağında henüz karar verilmemiştir. : İt a Test spin vermek es6fiddle.net
wintercounter

En son göre, bu işlevi vardır: wiki.ecmascript.org/doku.php?id=harmony:classes

Yanıtlar:


515

2018 güncellemesi:

Şimdi bir 3. aşama önerisi var - bu cevabı birkaç ay içinde geçersiz kılmak için sabırsızlanıyorum.

Bu arada, TypeScript veya babel kullanan herkes sözdizimini kullanabilir:

varName = value

Sınıf bildirimi / ifade gövdesi içinde bir değişken tanımlayacaktır. Umarım birkaç ay / hafta içinde bir güncelleme gönderebilirim.

Güncelleme: Chrome 74 şimdi bu sözdizimi ile birlikte geliyor.


ES6'daki teklif için ES wiki'deki notlar ( en az minimum sınıflar ) not:

Prototip veri özelliklerini (yöntemler dışında) sınıf özelliklerini veya örnek özelliğini tanımlamanın (kasıtlı olarak) doğrudan bildirici bir yolu yoktur.

Sınıf özellikleri ve prototip veri özellikleri, bildirimin dışında oluşturulmalıdır.

Sınıf tanımında belirtilen özelliklere, bir nesne değişmezinde görünenlerle aynı öznitelikler atanır.

Bu , sorduğunuz şeyin dikkate alındığı ve açıkça karşı çıkıldığı anlamına gelir .

ama neden?

İyi soru. TC39'un iyi insanları sınıf bildirimlerinin bir sınıfın yeteneklerini beyan etmesini ve tanımlamasını ister. Üyeleri değil. Bir ES6 sınıfı bildirisi, kullanıcısı için sözleşmesini tanımlar.

Unutmayın, bir sınıf tanımı prototip yöntemlerini tanımlar - prototip üzerindeki değişkenleri tanımlamak genellikle yaptığınız bir şey değildir. Elbette kullanabilirsiniz:

constructor(){
    this.foo = bar
}

Sizin gibi kurucu önerdi. Ayrıca fikir birliğinin özetine de bakınız .

ES7 ve sonrası

ES7 için, sınıf bildirimleri ve ifadeleri aracılığıyla daha özlü örnek değişkenlere izin veren yeni bir teklif üzerinde çalışılıyor - https://esdiscuss.org/topic/es7-property-initializers


4
@wintercounter bundan alınacak önemli şey, özelliklerin tanımlanmasına izin vermenin, onları her örnekte değil, yöntemlerde olduğu gibi prototip üzerinde tanımlamasıdır . Maksimum düzeyde minimal sınıflar hala çekirdek prototipsel mirastadır. Sizin durumunuzda gerçekten yapmak istediğiniz şey, paylaşım yapısı ve her örnek için üye atamaktır. ES6'daki sınıfların amaçladığı şey bu değildir - paylaşım işlevi. Yani evet, yapıyı paylaşmak için eski sözdizimine bağlı kalmanız gerekir. En az ES7'ye kadar :)
Benjamin

5
Sen söz isteyebilirsiniz staticözellikler
Bergi

8
Hata! Beyin osuruğu. staticSadece yöntemler için de işe yaradığını unuttum .
Bergi

637
Belki TC39'daki iyi insanlar, programlama dünyasının geri kalanı "sınıf" adlı bir şeyden beklediği gibi davranmasını istemiyorlarsa, bu kavramı "sınıf" dışında bir şey olarak adlandırmalıdırlar.
Alex

7
Ayrıca, "Sınıf Alanları ve Statik Özellikler" teklifine de (önceden Babel'de uygulanmıştır : github.com/jeffmo/es-class-fields-and-static-properties
Matt Browne

127

Sadece Benjamin'in cevap sınıfı değişkenlerine eklemek mümkündür, ancak prototypebunları ayarlamak için kullanamazsınız .

Gerçek bir sınıf değişkeni için aşağıdakine benzer bir şey yapmak istersiniz:

class MyClass {}
MyClass.foo = 'bar';

Bir sınıf yöntemi içinde bu değişkene this.constructor.foo(veya MyClass.foo) olarak erişilebilir .

Bu sınıf özelliklerine genellikle sınıf örneğinden erişilemez. yani MyClass.fooverir 'bar'ama new MyClass().fooolduğuundefined

Sınıf değişkeninize bir örnekten de erişmek istiyorsanız, ek olarak bir alıcı tanımlamanız gerekir:

class MyClass {
    get foo() {
        return this.constructor.foo;
    }
}

MyClass.foo = 'bar';

Bunu sadece Traceur ile test ettim, ancak standart bir uygulamada da aynı şekilde çalışacağına inanıyorum.

JavaScript'in gerçekten sınıfı yoktur . ES6 ile bile sınıf tabanlı bir dil yerine nesne veya prototip tabanlı bir dile bakıyoruz. Herhangi birinde function X () {}, X.prototype.constructorişaret eder X. Ne zaman newoperatör kullanılır X, yeni bir nesne miras oluşturulur X.prototype. Herhangi tanımsız (dahil yeni nesnede özellikleri constructor) oradan aranır. Bunu nesne ve sınıf özellikleri üretmek olarak düşünebiliriz.


29

Babel , ESNext'te sınıf değişkenlerini destekler, bu örneği kontrol edin :

class Foo {
  bar = 2
  static iha = 'string'
}

const foo = new Foo();
console.log(foo.bar, foo.iha, Foo.bar, Foo.iha);
// 2, undefined, undefined, 'string'

1
Sen yapabilir bar bir özel böyle "#" ile davranarak sınıf değişkeni: #bar = 2;
Lonnie En İyi

26

Örneğinizde:

class MyClass {
    const MY_CONST = 'string';
    constructor(){
        this.MY_CONST;
    }
}

MY_CONST ilkel olduğundan https://developer.mozilla.org/en-US/docs/Glossary/Primitive şunları yapabiliriz:

class MyClass {
    static get MY_CONST() {
        return 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

Ancak uyarı çıktısı MY_CONSTgibi başvuru türü dize ise, false . Bu durumda operatör hile yapabilir:static get MY_CONST() {return ['string'];}delete

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass

// alert: string ; true

Ve son olarak sınıf değişkeni için değil const:

class MyClass {
    static get MY_CONST() {
        delete MyClass.MY_CONST;
        return MyClass.MY_CONST = 'string';
    }
    static set U_YIN_YANG(value) {
      delete MyClass.MY_CONST;
      MyClass.MY_CONST = value;
    }
    get MY_CONST() {
        return this.constructor.MY_CONST;
    }
    set MY_CONST(value) {
        this.constructor.MY_CONST = value;
    }
    constructor() {
        alert(this.MY_CONST === this.constructor.MY_CONST);
    }
}
alert(MyClass.MY_CONST);
new MyClass
// alert: string, true
MyClass.MY_CONST = ['string, 42']
alert(MyClass.MY_CONST);
new MyClass
// alert: string, 42 ; true

5
deletePerformans nedenlerinden dolayı lütfen operatörden uzak durun. Aslında burada istediğin şey Object.defineProperty.
Bergi

@shinzou Aynı şeyi düşünüyordum. Yine de OP'nin hatası değil; gerçekte, verileri gerçek dünya ilişkilerini yansıtacak şekilde temsil etmek için uygun mekanizmalardan yoksun olan dildir.
user1974458

17

Sorununuz çoğunlukla stilistik olduğundan (kurucuyu bir sürü beyanla doldurmak istemeyen), stilistik olarak da çözülebilir.

Benim bakış açımdan, birçok sınıf tabanlı dil yapıcısı sınıf adının kendisinden sonra gelen bir işlev olabilir. Stilistik olarak bunu, stilistik olarak hala mantıklı olan ancak yapıcıda gerçekleşen tipik eylemleri yaptığımız tüm özellik bildirimleriyle gruplamayan bir ES6 sınıfı yapmak için kullanabiliriz. Sadece gerçek JS yapıcısını "bildirim alanı" olarak kullanırız, daha sonra "kurucu şeyler" alanı olarak değerlendirdiğimiz fonksiyon adlı bir sınıf yaparız ve onu gerçek kurucunun sonunda çağırırız.

"katı kullanın";

sınıf MyClass
{
    // sadece özelliklerinizi bildirin ve sonra bunu çağırın. ClassName (); buradan
    Yapıcı () {
        this.prop1 = 'filan 1';
        this.prop2 = 'filan 2';
        this.prop3 = 'filan 3';
        this.MyClass ();
    }

    // artık her türlü "yapıcı" malzeme, artık beyanlarla karıştırılmıyor
    Sınıfım() {
        ne istersen yap();
    }
}

Her ikisi de yeni örnek oluşturuldukça çağrılır.

Sortaları ve yapmak istediğiniz diğer kurucu eylemlerini ayırdığınız 2 kurucuya sahip olmak gibi ve stilistik olarak, neler olduğunu anlamak çok zor değil.

Çok sayıda bildirim ve / veya örneklemede gerçekleşmesi gereken ve iki fikri birbirinden ayrı tutmak isteyen birçok eylemle uğraşırken kullanmanın güzel bir stil olduğunu düşünüyorum.


NOT : Çok kasıtlı olarak "başlatma" ( init()ya da initialize()yöntem gibi ) tipik deyimsel fikirleri kullanmayın çünkü bunlar genellikle farklı kullanılır. İnşa etme ve başlatma fikri arasında bir tür varsayılan fark vardır. İnşaatçılar ile çalışan insanlar, kendilerine örneklemenin bir parçası olarak otomatik olarak çağrıldıklarını bilirler. initBirçok insanın ikinci bir bakış olmadan, form boyunca bir şeyler yapmaları gerektiğini varsayacağı bir yöntem gördüğünüz için var mc = MyClass(); mc.init();, genellikle bu şekilde başlatırsınız. Sınıfın kullanıcı için bir başlatma işlemi eklemeye çalışıyorum değilim, ben eklemek çalışıyorum için sınıfın kendisinin yapım sürecinin.

Bazı insanlar bir an için iki kere yapsalar da, asıl mesele budur: Onlara niyetin inşaatın bir parçası olduğunu bildirir, bu da onları biraz çift al ve git yapsa bile "bu değil ES6 kurucuları nasıl çalışır "ve gitmek için gerçek kurucuya bir saniye bakarak" oh, altta diyorlar, görüyorum ", bu niyetini iletmekten (veya yanlış bir şekilde iletmekten) ve muhtemelen bir sürü elde etmekten çok daha iyi insanlar yanlış kullanıyor, dışarıdan başlatmaya çalışıyor ve önemsiz. Bu önerdiğim kalıp için çok kasıtlı.


Bu paterni takip etmek istemeyenler için tam tersi de işe yarayabilir. Bildirimleri başlangıçta başka bir işleve göre düzenleyin. Belki "mülkler" veya "publicProperties" ya da başka bir ad verin. Sonra diğer şeyleri normal kurucuya koyun.

"katı kullanın";

sınıf MyClass
{
    özellikleri() {
        this.prop1 = 'filan 1';
        this.prop2 = 'filan 2';
        this.prop3 = 'filan 3';
    }

    constructor () {
        this.properties ();
        ne istersen yap();
    }
}

Bu ikinci yöntemin daha temiz görünebileceğini, ancak propertiesbu yöntemi kullanarak bir sınıfın başka bir sınıfı genişletmesiyle geçersiz kılındığı doğal bir sorun olduğunu unutmayın . Bundan propertieskaçınmak için daha benzersiz adlar vermeniz gerekir . İlk metodumda bu sorun yok çünkü kurucunun sahte yarısı dersten sonra adlandırılıyor.


1
Lütfen sınıfın adını taşıyan bir prototip yöntemi kullanmayın. Bu JS'de deyimsel değil, başka bir dil gibi görünmeye çalışmayın. Bu yaklaşımı gerçekten kullanmak istiyorsanız, yöntemin standart adıdır init.
Bergi

1
@Bergi - initsık kullanılan ve genellikle dış kullanıcı başlatmak istediğinde sınıfın dışından çağrılması gereken bir kalıptır var b = new Thing(); b.init();. Bu, diğer dillerde bulunan desenlerden yararlanarak otomatik olarak çağrılan 2. bir işlev olduğunu bildirmeyi tercih ettiğim% 100 stilistik bir seçimdir. Birinin buna bakması ve MyClassyöntemi dışarıdan çağırması gerektiğini varsayması çok daha az olasıdır , niyetin inşaatta hareket eden 2. bir yöntem olduğunu (yani kendiliğinden örnekleme olarak adlandırılır) fark etmeleri daha olasıdır.
Jimbo Jonny

Hm, bunu yapıcıya bakarak fark edebilirim, ancak yöntem adından değil MyClass.
Bergi

1
@Bergi - Başka bir dilden bir desen almak ve bunu JS'ye teknik olarak olan, ancak hala işe yaramayan bir şekilde uygulamak, tamamen emsalsiz değildir. Kimsenin $myvarjQuery nesnelerini tutmaya yönelik değişkenlere atıfta bulunmanın standart yolunun, pek çok PHP programcısının alışkın olduğu değişkenlerin başında $ sahip olma modeline uygun olmadığını kimsenin farketmediğini söyleyemezsiniz . "Evet, aynı şey değil ... ama bak ... hala bir değişken çünkü değişkenlerin bazı dillerde yapılmasının bir yolu!" yardım eder.
Jimbo Jonny

1
Ben properties()fonksiyonu ile son seçenek tercih . Ancak, işler Sana bir kullanırsanız öneririm böylece sınıflar uzanan zaman daha karmaşık biraz olsun properties(): (IE sınıfların tümünde işlevini sınıf adıyla yöntem adı öneki olduğunu size bir sınıf özelliklerini beyan etmek MyClassProperties()yanlışlıkla önlemek için geçersiz kılma alt sınıflar içindeki işlev çağrıları Ayrıca, tüm super()yapıcıların önce sınıf yapıcısında bildirilmesi gerektiğini unutmayın
TheDarkIn1978

14

Peki ya eski okul yolu?

class MyClass {
     constructor(count){ 
          this.countVar = 1 + count;
     }
}
MyClass.prototype.foo = "foo";
MyClass.prototype.countVar = 0;

// ... 

var o1 = new MyClass(2); o2 = new MyClass(3);
o1.foo = "newFoo";

console.log( o1.foo,o2.foo);
console.log( o1.countVar,o2.countVar);

Yapıcıda sadece hesaplanması gereken değişkenlerden bahsedersiniz. Bu özellik için prototip mirasını seviyorum - çok fazla bellek tasarrufu yapmanıza yardımcı olabilir (hiç atanmamış değişkenler varsa).


4
Bu bellek tasarrufu yapmaz ve performansı yapıcıda bildirmiş olduğunuzdan çok daha kötü hale getirir. codereview.stackexchange.com/a/28360/9258
Esailija

2
Ayrıca, bu ES6 sınıflarını ilk etapta kullanmayı amaçlamaktadır. Olduğu gibi, gerçek oop sınıfları gibi ES6 sınıflarını kullanmak neredeyse imkansız görünüyor, ki bu biraz hayal kırıklığı yaratıyor ...
Kokodoko

4
@Kokodoko real oop - yani, Java'daki gibi mi? Katılıyorum, bir çok insanın JS'ye kızgın olduğunu fark ettim, çünkü Java gibi kullanmaya çalışıyorlar, alıştıkları gibi, JS sözdizimi benzer görünüyor ve aynı şekilde çalıştığını varsayıyorlar ... Ama içeride, bildiğimiz gibi oldukça farklı.
zarkone

2
Bu sadece dil sözdizimi ile ilgili değil. OOP felsefesi genel olarak programlamaya oldukça uygundur - özellikle uygulamalar ve oyunlar oluştururken. JS geleneksel olarak oldukça farklı web sayfalarının oluşturulmasında uygulanmıştır. Bir şekilde bu iki yaklaşımın bir araya gelmesi gerekiyor, çünkü web de uygulamalar hakkında daha fazla hale geliyor.
Kokodoko

1
@Kokodoko Sadece bir çünkü farklı anlamına gelmez cepten değildir OOP. Prototipler% 100 geçersiz OOP yaklaşımıdır; hiç kimse Öz'e “OOP olmayan” demeyecektir çünkü prototipleri kullanır. Başka bir OOP paradigmasıyla eşleşmemek sadece şu anlama gelir: farklı.
Dave Newton

13

Benjamin yanıtında söylediği gibi, TC39 bu özelliği en azından ES2015 için dahil etmemeye açıkça karar verdi. Ancak, fikir birliği ES2016'ya ekleyecek gibi görünüyor.

Sözdizimi henüz kararlaştırılmadı, ancak ES2016 için bir sınıfta statik özellikler bildirmenize izin verecek bir ön teklif var .

Babil büyüsü sayesinde, bunu bugün kullanabilirsiniz. Sınıf özellikleri dönüşümünü bu talimatlara göre etkinleştirin ve hazırsınız. İşte sözdiziminin bir örneği:

class foo {
  static myProp = 'bar'
  someFunction() {
    console.log(this.myProp)
  }
}

Bu teklif çok erken bir durumda, bu yüzden zaman geçtikçe sözdizimini değiştirmeye hazır ol.


Evet, bu ES6 değil. Ne olduğunu bilmediğiniz sürece kullanmamalısınız.
Bergi

10

[Uzun iplik, zaten bir seçenek olarak listelenip listelenmediğinden emin değilim ...]. Sadece uzlaşmacılar için
basit bir alternatif , sınıfın dışındaki bir katı tanımlamak olacaktır. Bu alıcıya eşlik etmedikçe sadece modülün kendisinden erişilebilir.
Bu şekilde prototypeçöp değil ve sen const.

// will be accessible only from the module itself
const MY_CONST = 'string'; 
class MyClass {

    // optional, if external access is desired
    static get MY_CONST(){return MY_CONST;}

    // access example
    static someMethod(){
        console.log(MY_CONST);
    }
}

A) 2 varyerine bir) kullanırsanız constbu sınıfın birden çok örneğini kullanırsanız ne olur ? Daha sonra dış değişkenler sınıfın her bir örneğiyle değiştirilecektir
nick carraway

1
fail point @nickcarraway, teklifim başlıklı soru olarak değil, sadece const anlamına gelir.
Hertzel Guinness

6

ES7 sınıf üyesi sözdizimi:

ES7yapıcı fonksiyonunuzu 'junking' için bir çözüme sahiptir. İşte bir örnek:

class Car {
  
  wheels = 4;
  weight = 100;

}

const car = new Car();
console.log(car.wheels, car.weight);

Yukarıdaki örnek şu şekilde görünecektir ES6:

class Car {

  constructor() {
    this.wheels = 4;
    this.weight = 100;
  }

}

const car = new Car();
console.log(car.wheels, car.weight);

Bunu kullanırken, bu sözdiziminin tüm tarayıcılar tarafından desteklenmeyebileceğini ve önceki bir JS sürümünün aktarılması gerekebileceğini unutmayın.

Bonus: bir nesne fabrikası:

function generateCar(wheels, weight) {

  class Car {

    constructor() {}

    wheels = wheels;
    weight = weight;

  }

  return new Car();

}


const car1 = generateCar(4, 50);
const car2 = generateCar(6, 100);

console.log(car1.wheels, car1.weight);
console.log(car2.wheels, car2.weight);


3
Sınıf değişkenlerini değil, örnek değişkenlerini tamamladınız.
Tjad Clark

5

Es6 sınıflarının davranışını taklit edebilir ve sınıf değişkenlerinizi kullanabilirsiniz :)

Bak anne ... ders yok!

// Helper
const $constructor = Symbol();
const $extends = (parent, child) =>
  Object.assign(Object.create(parent), child);
const $new = (object, ...args) => {
  let instance = Object.create(object);
  instance[$constructor].call(instance, ...args);
  return instance;
}
const $super = (parent, context, ...args) => {
  parent[$constructor].call(context, ...args)
}
// class
var Foo = {
  classVariable: true,

  // constructor
  [$constructor](who){
    this.me = who;
    this.species = 'fufel';
  },

  // methods
  identify(){
    return 'I am ' + this.me;
  }
}

// class extends Foo
var Bar = $extends(Foo, {

  // constructor
  [$constructor](who){
    $super(Foo, this, who);
    this.subtype = 'barashek';
  },

  // methods
  speak(){
    console.log('Hello, ' + this.identify());
  },
  bark(num){
    console.log('Woof');
  }
});

var a1 = $new(Foo, 'a1');
var b1 = $new(Bar, 'b1');
console.log(a1, b1);
console.log('b1.classVariable', b1.classVariable);

GitHub'a koydum


0

Başka bir seçenek olan (jQuery varsa) bunu çözdüğüm yol, eski okul nesnesindeki alanları tanımlamak ve ardından sınıfı bu nesne ile genişletmektir. Ayrıca yapıcıyı ödevlerle biberlemek istemedim, bu temiz bir çözüm gibi görünüyordu.

function MyClassFields(){
    this.createdAt = new Date();
}

MyClassFields.prototype = {
    id : '',
    type : '',
    title : '',
    createdAt : null,
};

class MyClass {
    constructor() {
        $.extend(this,new MyClassFields());
    }
};

- Güncelleme Bergi'nin yorumunu takiben.

JQuery Sürümü Yok:

class SavedSearch  {
    constructor() {
        Object.assign(this,{
            id : '',
            type : '',
            title : '',
            createdAt: new Date(),
        });

    }
}

Hala 'şişman' yapıcı ile sonuçlanırsınız, ama en azından hepsi bir sınıfta ve bir vuruşta görevlendirilmiş.

DÜZENLEME # 2: Şimdi tam daireye gittim ve şimdi yapıcıya değerler ataıyorum, ör.

class SavedSearch  {
    constructor() {
        this.id = '';
        this.type = '';
        this.title = '';
        this.createdAt = new Date();
    }
}

Neden? Çok basit, yukarıdaki artı bazı JSdoc yorumları kullanarak, PHPStorm özellikleri üzerinde kod tamamlama gerçekleştirebildi. Tek bir vuruşta tüm değişkenleri atamak güzeldi, ancak özellikleri tamamlayamama imo, imo, (neredeyse kesinlikle küçük) performans faydasına değmez.


2
Eğer classsentaks yapabiliyorsanız, yapabilirsiniz Object.assign. JQuery'ye gerek yok.
Bergi

MyClassFieldsBir kurucu yapmak için hiçbir nokta görmüyorum - herhangi bir yöntemi yok. Bunu neden yaptığınızı (örneğin, bir nesne değişmezini döndüren basit bir fabrika işlevi yerine) ayrıntılı olarak açıklayabilir misiniz?
Bergi

@Bergi - Muhtemelen dürüst olmak gerekirse her şeyden ziyade alışkanlık gücü. Ayrıca Object.assign hakkında güzel bir çağrı - bunu bilmiyordum!
Steve Childs

0

Yapıcı içindeki değişkenleri bildirebilirsiniz.

class Foo {
    constructor() {
        var name = "foo"
        this.method = function() {
            return name
        }
    }
}

var foo = new Foo()

foo.method()

1
Bu değişkeni kullanmak için bu sınıfın bir örneğini oluşturmanız gerekir. Statik işlevler bu değişkene erişemez
Aditya

0

Yine de başka bir programlama dilinde olduğu gibi hiçbir sınıf bildiremezsiniz. Ancak çok sayıda sınıf değişkeni oluşturabilirsiniz. Ancak problem sınıf nesnesinin kapsamıdır. Yani bana göre, ES6 Javascript en iyi yolu OOP Programlama: -

class foo{
   constructor(){
     //decalre your all variables
     this.MY_CONST = 3.14;
     this.x = 5;
     this.y = 7;
     // or call another method to declare more variables outside from constructor.
     // now create method level object reference and public level property
     this.MySelf = this;
     // you can also use var modifier rather than property but that is not working good
     let self = this.MySelf;
     //code ......... 
   }
   set MySelf(v){
      this.mySelf = v;
   }
   get MySelf(v){
      return this.mySelf;
   }
   myMethod(cd){
      // now use as object reference it in any method of class
      let self = this.MySelf;
      // now use self as object reference in code
   }
}

-1

Bu biraz statik statik bir kombinasyon ve benim için çalışır olsun

class ConstantThingy{
        static get NO_REENTER__INIT() {
            if(ConstantThingy._NO_REENTER__INIT== null){
                ConstantThingy._NO_REENTER__INIT = new ConstantThingy(false,true);
            }
            return ConstantThingy._NO_REENTER__INIT;
        }
}

başka yerde kullanılmış

var conf = ConstantThingy.NO_REENTER__INIT;
if(conf.init)...

7
singleton_instanceHerkesin burada ne yaptığını anlaması için bir mülk adı olarak tavsiye ederim .
Bergi
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.