Alternatif variabel kelas ES6

493

Saat ini di ES5 banyak dari kita menggunakan pola berikut dalam kerangka kerja untuk membuat kelas dan variabel kelas, yang nyaman:

// ES 5
FrameWork.Class({

    variable: 'string',
    variable2: true,

    init: function(){

    },

    addItem: function(){

    }

});

Di ES6 Anda dapat membuat kelas secara native, tetapi tidak ada opsi untuk memiliki variabel kelas:

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

Sayangnya, hal di atas tidak akan berhasil, karena hanya kelas yang bisa berisi metode.

Saya mengerti bahwa saya bisa this.myVar = truemasuk constructor... tapi saya tidak ingin 'membuang' konstruktor saya, terutama ketika saya memiliki 20-30 + params untuk kelas yang lebih besar.

Saya sedang memikirkan banyak cara untuk menangani masalah ini, tetapi belum menemukan yang bagus. (Misalnya: membuat ClassConfighandler, dan meneruskan parameterobjek, yang dideklarasikan secara terpisah dari kelas. Kemudian handler akan melampirkan ke kelas. WeakMapsEntah bagaimana saya juga mengintegrasikan, entah bagaimana.)

Gagasan apa yang akan Anda miliki untuk menangani situasi ini?

musim dingin
sumber
1
masalah utama Anda adalah bahwa Anda akan memiliki pengulangan this.member = memberdi konstruktor Anda dengan 20-30 parameter?
Θεόφιλος Μουρατίδης
1
Tidak bisakah kamu menggunakan di public variable2 = truebawah kelas saja? Ini akan mendefinisikannya pada prototipe.
14
@ Θεόφιλος Μουρατίδης: Ya, dan saya juga ingin menggunakan konstruktor saya untuk prosedur inisialisasi dan bukan untuk deklarasi variabel.
musim dingin
@derylius: Ini adalah masalah utama, tidak memiliki fitur seperti itu. Bahkan penggunaan publik / pribadi belum diputuskan dalam draft ES6. Memberikan test berputar: es6fiddle.net
wintercounter
Menurut yang terbaru, ia memiliki fungsi ini: wiki.ecmascript.org/doku.php?id=harmony:classes

Jawaban:

515

Pembaruan 2018:

Sekarang ada proposal tahap 3 - Saya berharap untuk membuat jawaban ini menjadi usang dalam beberapa bulan.

Sementara itu siapa pun yang menggunakan TypeScript atau babel dapat menggunakan sintaks:

varName = value

Di dalam badan deklarasi / ekspresi kelas dan itu akan mendefinisikan variabel. Semoga dalam beberapa bulan / minggu saya dapat memposting pembaruan.

Pembaruan: Chrome 74 sekarang hadir dengan sintaks ini berfungsi.


Catatan dalam wiki ES untuk proposal dalam ES6 ( kelas maksimal minimal ) catatan:

Tidak ada (sengaja) tidak ada cara deklaratif langsung untuk mendefinisikan properti data prototipe (selain metode) kelas properti, atau properti instance

Properti kelas dan properti data prototipe perlu dibuat di luar deklarasi.

Properti yang ditentukan dalam definisi kelas diberi atribut yang sama seolah-olah mereka muncul dalam objek literal.

Ini berarti bahwa apa yang Anda minta dipertimbangkan, dan secara eksplisit memutuskan untuk tidak melakukannya.

tapi kenapa?

Pertanyaan bagus. Orang-orang baik di TC39 menginginkan deklarasi kelas untuk mendeklarasikan dan mendefinisikan kemampuan suatu kelas. Bukan anggotanya. Deklarasi kelas ES6 mendefinisikan kontraknya untuk penggunanya.

Ingat, definisi kelas mendefinisikan metode prototipe - mendefinisikan variabel pada prototipe umumnya bukan sesuatu yang Anda lakukan. Anda tentu saja dapat menggunakan:

constructor(){
    this.foo = bar
}

Di konstruktor seperti yang Anda sarankan. Lihat juga ringkasan konsensus .

ES7 dan selanjutnya

Proposal baru untuk ES7 sedang dikerjakan yang memungkinkan variabel instance yang lebih ringkas melalui deklarasi dan ekspresi kelas - https://esdiscuss.org/topic/es7-property-initializers

Benjamin Gruenbaum
sumber
4
@wintercounter hal penting untuk diambil darinya adalah mengizinkan properti pendefinisian akan mendefinisikannya pada prototipe seperti metode dan bukan pada setiap instance. Maksimal kelas-kelas yang minimal masih merupakan warisan inti prototipikal. Apa yang benar-benar ingin Anda lakukan dalam kasus Anda adalah struktur berbagi dan menugaskan anggota untuk setiap contoh. Ini bukan tujuan kelas ES6 untuk - berbagi fungsi. Jadi ya, untuk struktur berbagi Anda harus tetap menggunakan sintaks lama. Setidaknya sampai ES7 :)
Benjamin Gruenbaum
5
Anda mungkin ingin menyebutkan staticproperti
Bergi
8
Ups, kentut otak. Saya lupa itu statichanya berfungsi untuk metode.
Bergi
638
Mungkin orang-orang baik di TC39 seharusnya menamai konsep ini dengan sesuatu yang bukan "kelas" jika mereka tidak ingin berperilaku seperti yang diharapkan oleh dunia pemrograman lain dari sesuatu yang bernama "kelas".
Alex
7
Lihat juga proposal "Properti Lapangan & Properti Statis" (sudah diterapkan di Babel : github.com/jeffmo/es-class-fields-and-static-properties
Matt Browne
127

Hanya untuk menambah jawaban Benjamin - variabel kelas dimungkinkan, tetapi Anda tidak akan menggunakannya prototypeuntuk mengaturnya.

Untuk variabel kelas sejati, Anda ingin melakukan sesuatu seperti berikut:

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

Dari dalam metode kelas variabel itu dapat diakses sebagai this.constructor.foo(atau MyClass.foo).

Properti kelas ini biasanya tidak dapat diakses dari ke instance kelas. yaitu MyClass.foomemberi 'bar'tapi new MyClass().fooadalahundefined

Jika Anda juga ingin memiliki akses ke variabel kelas Anda dari instance, Anda juga harus mendefinisikan pengambil:

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

MyClass.foo = 'bar';

Saya hanya menguji ini dengan Traceur, tetapi saya percaya ini akan bekerja sama dalam implementasi standar.

JavaScript tidak benar-benar memiliki kelas . Bahkan dengan ES6 kita melihat bahasa berbasis objek atau prototipe daripada bahasa berbasis kelas. Dalam hal apa pun function X () {}, X.prototype.constructorpoin kembali ke X. Ketika newoperator digunakan X, objek baru dibuat mewarisi X.prototype. Setiap properti yang tidak terdefinisi di objek baru itu (termasuk constructor) dilihat dari sana. Kita dapat menganggap ini sebagai menghasilkan objek dan properti kelas.

lyschoening
sumber
29

Babel mendukung variabel kelas di ESNext, periksa contoh ini :

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'
Kosmetika
sumber
1
Anda dapat membuat bar sebuah pribadi variabel kelas dengan berpura-pura dengan "#" seperti ini: #bar = 2;
Lonnie Best
26

Dalam contoh Anda:

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

Karena MY_CONST adalah primitif https://developer.mozilla.org/en-US/docs/Glossary/Primitive yang bisa kita lakukan:

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

Tetapi jika MY_CONSTtipe referensi seperti static get MY_CONST() {return ['string'];}keluaran peringatan adalah string, false . Dalam hal ini deleteoperator dapat melakukan trik:

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

Dan akhirnya untuk variabel kelas tidak 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
Oleg Mazko
sumber
5
Harap hindari deleteoperator, jika sendirian karena alasan kinerja. Apa yang sebenarnya Anda inginkan di sini adalah Object.defineProperty.
Bergi
@ Shinzou, aku memikirkan hal yang sama. Meskipun demikian, belum tentu kesalahan OP; itu benar-benar bahasa yang tidak memiliki mekanisme yang tepat untuk merepresentasikan data dengan cara yang mencerminkan hubungan dunia nyata.
user1974458
17

Karena masalah Anda sebagian besar bergaya (tidak ingin mengisi konstruktor dengan banyak deklarasi), itu dapat diselesaikan dengan gaya juga.

Cara saya melihatnya, banyak bahasa berbasis kelas memiliki konstruktor menjadi fungsi yang dinamai dengan nama kelas itu sendiri. Secara gaya kita dapat menggunakannya untuk membuat kelas ES6 yang secara gaya masih masuk akal tetapi tidak mengelompokkan tindakan khas yang terjadi di konstruktor dengan semua deklarasi properti yang kami lakukan. Kami cukup menggunakan konstruktor JS aktual sebagai "area deklarasi", lalu membuat fungsi kelas bernama yang sebaliknya kami perlakukan sebagai area "konstruktor lain", menyebutnya di akhir konstruktor yang sebenarnya.

"gunakan ketat";

kelas MyClass
{
    // hanya nyatakan properti Anda dan panggil ini.ClassName (); dari sini
    constructor () {
        this.prop1 = 'blah 1';
        this.prop2 = 'blah 2';
        this.prop3 = 'blah 3';
        this.MyClass ();
    }

    // segala macam hal "konstruktor" lainnya, tidak lagi campur aduk dengan deklarasi
    Kelasku() {
        lakukan Apa pun ();
    }
}

Keduanya akan disebut sebagai instance baru dibangun.

Agak seperti memiliki 2 konstruktor di mana Anda memisahkan deklarasi dan tindakan konstruktor lain yang ingin Anda ambil, dan secara gaya membuatnya tidak terlalu sulit untuk memahami apa yang sedang terjadi juga.

Saya menemukan itu adalah gaya yang baik untuk digunakan ketika berhadapan dengan banyak deklarasi dan / atau banyak tindakan yang perlu terjadi pada instantiasi dan ingin menjaga dua ide berbeda satu sama lain.


CATATAN : Saya sangat sengaja tidak menggunakan ide idiomatik khas "menginisialisasi" (seperti metode init()atau initialize()) karena mereka sering digunakan secara berbeda. Ada semacam perbedaan dugaan antara gagasan membangun dan menginisialisasi. Bekerja dengan konstruktor, orang-orang tahu bahwa mereka dipanggil secara otomatis sebagai bagian dari Instansiasi. Melihat initmetode yang akan diasumsikan oleh banyak orang tanpa pandangan kedua bahwa mereka perlu melakukan sesuatu dalam bentuk var mc = MyClass(); mc.init();, karena itulah cara Anda biasanya menginisialisasi. Aku tidak mencoba untuk menambahkan proses inisialisasi untuk pengguna kelas, aku mencoba untuk menambahkan ke proses pembangunan kelas itu sendiri.

Sementara beberapa orang mungkin melakukan pengambilan ganda untuk sesaat, itu sebenarnya intinya: itu menyampaikan kepada mereka bahwa maksudnya adalah bagian dari konstruksi, bahkan jika itu membuat mereka melakukan sedikit pengambilan ganda dan pergi "itu bukan bagaimana konstruktor ES6 bekerja "dan luangkan waktu sejenak melihat konstruktor yang sebenarnya untuk pergi" oh, mereka menyebutnya di bagian bawah, saya mengerti ", itu jauh lebih baik daripada TIDAK mengomunikasikan maksud itu (atau salah mengomunikasikannya) dan mungkin mendapatkan banyak orang menggunakannya salah, mencoba menginisialisasi dari luar dan sampah. Itu sangat disengaja dengan pola yang saya sarankan.


Bagi mereka yang tidak ingin mengikuti pola itu, kebalikannya bisa juga. Perkuat deklarasi ke fungsi lain di awal. Mungkin nama itu "properti" atau "properti publik" atau sesuatu. Kemudian letakkan sisanya di konstruktor normal.

"gunakan ketat";

kelas MyClass
{
    properti () {
        this.prop1 = 'blah 1';
        this.prop2 = 'blah 2';
        this.prop3 = 'blah 3';
    }

    constructor () {
        properti ini ();
        lakukan Apa pun ();
    }
}

Perhatikan bahwa metode kedua ini mungkin terlihat lebih bersih tetapi juga memiliki masalah yang melekat di mana propertiesakan ditimpa karena satu kelas menggunakan metode ini meluas yang lain. Anda harus memberikan lebih banyak nama unik propertiesuntuk menghindari hal itu. Metode pertama saya tidak memiliki masalah ini karena setengah palsu dari konstruktor secara unik dinamai setelah kelas.

Jimbo Jonny
sumber
1
Tolong jangan gunakan metode prototipe bernama setelah kelas itu sendiri. Itu non-idiomatis di JS, jangan mencoba membuatnya terlihat seperti bahasa lain. Jika Anda benar-benar ingin menggunakan pendekatan ini, nama kanonik untuk metode ini adalah init.
Bergi
1
@Bergi - initadalah pola yang sering digunakan, dan sering dimaksudkan untuk dipanggil dari luar kelas ketika pengguna luar ingin menginisialisasi, yaitu var b = new Thing(); b.init();. Ini adalah pilihan gaya 100% yang saya lebih suka untuk berkomunikasi bahwa itu adalah fungsi ke-2 yang secara otomatis dipanggil dengan mengambil keuntungan dari pola yang ditemukan dalam bahasa lain. Jauh lebih kecil kemungkinannya seseorang akan melihat ini dan menganggap bahwa mereka perlu memanggil MyClassmetode dari luar, lebih mungkin bahwa mereka akan menyadari maksudnya adalah metode ke-2 yang bertindak dalam konstruksi (yaitu dipanggil dengan sendirinya pada instantiasi).
Jimbo Jonny
Hm, saya mungkin menyadari bahwa dengan melihat konstruktor, tetapi tidak dari nama metode MyClass.
Bergi
1
@Bergi - Mengambil pola dari bahasa lain dan menerapkannya ke JS dengan cara yang tidak secara teknis apa yang terjadi, tetapi masih berfungsi tidak sepenuhnya tanpa preseden. Anda tidak dapat memberi tahu saya bahwa tidak ada seorang pun yang memperhatikan bahwa $myvarcara standar untuk merujuk ke variabel yang dimaksudkan untuk menampung objek jQuery tidak nyaman mirip dengan pola memiliki $ pada awal variabel yang digunakan oleh begitu banyak programmer PHP. Hanya sedikit implikasi bahwa "ya, itu bukan hal yang persis sama ... tapi lihat ... itu masih variabel karena itu adalah cara variabel dilakukan dalam beberapa bahasa!" membantu.
Jimbo Jonny
1
Saya lebih suka opsi terakhir Anda dengan properties()fungsi. Namun, hal-hal menjadi sedikit lebih rumit ketika memperluas kelas jadi saya akan menyarankan bahwa jika Anda menggunakan properties()fungsi di semua kelas Anda untuk mendeklarasikan Anda properti kelas yang Anda awali nama metode dengan nama kelas (IE: MyClassProperties()untuk menghindari overriding tanpa sengaja panggilan fungsi di dalam sub kelas. Juga, perlu diingat bahwa panggilan apa pun super()harus dideklarasikan terlebih dahulu di konstruktor kelas.
TheDarkIn1978
14

Bagaimana dengan cara oldschool?

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);

Dalam konstruktor Anda hanya menyebutkan vars yang harus dihitung. Saya suka warisan prototipe untuk fitur ini - ini dapat membantu menghemat banyak memori (kalau-kalau ada banyak vars yang tidak pernah ditugaskan).

Zarkone
sumber
4
Ini tidak menghemat memori dan itu hanya membuat kinerja jauh lebih buruk daripada jika Anda mendeklarasikannya di konstruktor. codereview.stackexchange.com/a/28360/9258
Esailija
2
Juga, ini mengalahkan tujuan menggunakan kelas ES6 di tempat pertama. Seperti kelihatannya, tampaknya tidak mungkin untuk menggunakan kelas ES6 seperti kelas oop nyata, yang agak mengecewakan ...
Kokodoko
4
@Kokodoko oop nyata - maksudmu, seperti misalnya di Jawa? Saya setuju, saya perhatikan bahwa banyak orang yang marah kepada JS karena mereka mencoba menggunakannya seperti Java, seperti mereka terbiasa, karena sintaks JS terlihat mirip, dan mereka menganggap itu bekerja dengan cara yang sama ... Tapi dari di dalam, itu sangat berbeda, seperti yang kita tahu.
zarkone
2
Ini bukan hanya tentang sintaks bahasa. Filosofi OOP cocok untuk pemrograman secara umum - terutama ketika membuat aplikasi dan game. JS secara tradisional telah diterapkan dalam membangun halaman web yang sangat berbeda. Entah bagaimana kedua pendekatan itu perlu disatukan, karena web juga menjadi lebih banyak tentang aplikasi.
Kokodoko
1
@ Kodokoko Hanya karena itu OOP yang berbeda bukan berarti bukan OOP. Prototipe adalah pendekatan OOP 100% valid; tidak ada yang akan menyebut Diri "non-OOP" karena menggunakan prototipe. Tidak cocok dengan paradigma OOP lain hanya berarti: itu berbeda.
Dave Newton
13

Seperti yang dikatakan Benjamin dalam jawabannya, TC39 secara eksplisit memutuskan untuk tidak menyertakan fitur ini setidaknya untuk ES2015. Namun, konsensus tampaknya bahwa mereka akan menambahkannya di ES2016.

Sintaksnya belum diputuskan, tetapi ada proposal awal untuk ES2016 yang akan memungkinkan Anda untuk mendeklarasikan properti statis di kelas.

Berkat keajaiban babel, Anda dapat menggunakannya hari ini. Aktifkan transformasi properti kelas sesuai dengan instruksi ini dan Anda siap melakukannya. Berikut ini contoh sintaksnya:

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

Proposal ini dalam kondisi sangat awal, jadi bersiaplah untuk mengubah sintaks Anda seiring berjalannya waktu.

BonsaiOak
sumber
Ya, itu bukan ES6. Kecuali Anda tahu apa itu, Anda tidak boleh menggunakannya.
Bergi
10

[Utas panjang, tidak yakin apakah sudah terdaftar sebagai opsi ...].
Sebuah sederhana alternatif untuk contsants hanya , akan mendefinisikan luar const kelas. Ini akan dapat diakses hanya dari modul itu sendiri, kecuali disertai dengan pengambil.
Cara prototypeini tidak dikotori dan Anda mendapatkan 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);
    }
}
Hertzel Guinness
sumber
Apa yang terjadi jika Anda a) menggunakan a varbukannya const2) menggunakan beberapa instance kelas ini? Kemudian variabel eksternal akan diubah dengan setiap instance dari kelas
nick carraway
1
titik gagal @nickcarraway, penawaran saya hanya untuk const, bukan sebagai pertanyaan berjudul.
Hertzel Guinness
6

ES7 sintaks anggota kelas:

ES7memiliki solusi untuk 'membuang sampah' fungsi konstruktor Anda. Berikut ini sebuah contoh:

class Car {
  
  wheels = 4;
  weight = 100;

}

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

Contoh di atas akan terlihat sebagai berikut ES6:

class Car {

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

}

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

Berhati-hatilah saat menggunakan ini bahwa sintaks ini mungkin tidak didukung oleh semua browser dan mungkin harus ditransmisikan ke versi JS yang lebih lama.

Bonus: pabrik objek:

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);

Willem van der Veen
sumber
3
Anda telah menyelesaikan variabel instan, bukan variabel kelas.
Tjad Clark
5

Anda dapat meniru perilaku kelas es6 ... dan menggunakan variabel kelas Anda :)

Lihat bu ... tidak ada kelas!

// 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);

Saya menaruhnya di GitHub

Ruslan
sumber
0

Cara saya memecahkan ini, yang merupakan pilihan lain (jika Anda memiliki jQuery tersedia), adalah untuk Menentukan bidang dalam objek old-school dan kemudian memperluas kelas dengan objek itu. Saya juga tidak ingin membumbui konstruktor dengan tugas, ini tampaknya menjadi solusi yang rapi.

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

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

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

- Perbarui Mengikuti komentar Bergi.

Tidak Ada Versi JQuery:

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

    }
}

Anda masih berakhir dengan konstruktor 'gemuk', tetapi setidaknya semuanya dalam satu kelas dan ditugaskan dalam satu pukulan.

EDIT # 2: Sekarang saya sudah menjadi lingkaran penuh dan sekarang saya memberikan nilai dalam konstruktor, misalnya

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

Mengapa? Sederhana banget, menggunakan komentar JSdoc di atas ditambah beberapa, PHPStorm mampu melakukan penyelesaian kode pada properti. Menetapkan semua vars dalam satu pukulan bagus, tetapi ketidakmampuan untuk menyelesaikan kode properti, imo, tidak sebanding dengan manfaat kinerja (hampir pasti sangat kecil).

Steve Childs
sumber
2
Jika Anda dapat melakukan classsintaks, Anda juga dapat melakukannya Object.assign. Tidak perlu jQuery.
Bergi
Saya tidak melihat titik untuk membuat MyClassFieldskonstruktor - tidak ada metode. Bisakah Anda menguraikan mengapa Anda melakukan ini (alih-alih, katakanlah, fungsi pabrik sederhana yang mengembalikan objek literal)?
Bergi
@Bergi - Mungkin kekuatan kebiasaan daripada yang lain, jujur. Juga panggilan yang bagus tentang Object.assign - tidak tahu tentang itu!
Steve Childs
0

Anda dapat mendeklarasikan variabel di dalam konstruktor.

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

var foo = new Foo()

foo.method()
Osama Xäwãñz
sumber
1
Anda harus membuat turunan dari kelas ini untuk menggunakan variabel ini. Fungsi statis tidak dapat mengakses variabel itu
Aditya
0

Tetap saja Anda tidak dapat mendeklarasikan kelas seperti di bahasa pemrograman lain. Tetapi Anda bisa membuat banyak variabel kelas. Tetapi masalah adalah ruang lingkup objek kelas. Jadi Menurut saya, Cara terbaik Pemrograman OOP di ES6 Javascript: -

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
   }
}
Tyler
sumber
-1

Ini adalah kombo agak statis statis dan mendapatkan pekerjaan untuk saya

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;
        }
}

digunakan di tempat lain

var conf = ConstantThingy.NO_REENTER__INIT;
if(conf.init)...
TroyWorks
sumber
7
Saya akan merekomendasikan singleton_instancesebagai nama properti sehingga semua orang mengerti apa yang Anda lakukan di sini.
Bergi