Rumah  >  Artikel  >  hujung hadapan web  >  Pelajari corak reka bentuk JavaScript (enkapsulasi)_kemahiran javascript

Pelajari corak reka bentuk JavaScript (enkapsulasi)_kemahiran javascript

WBOY
WBOYasal
2016-05-16 15:29:421012semak imbas

Dalam JavaScript, tiada sokongan untuk kelas abstrak dan antara muka. JavaScript itu sendiri juga merupakan bahasa yang ditaip lemah. JavaScript tidak mempunyai keupayaan atau perlu melakukan lebih banyak lagi apabila ia berkaitan dengan jenis merangkum. Untuk pelaksanaan corak reka bentuk dalam JavaScript, tidak membezakan jenis adalah memalukan, dan ia juga boleh dikatakan melegakan.

Dari perspektif corak reka bentuk, pembungkusan dicerminkan dalam perubahan pembungkusan pada tahap yang lebih penting.

Dengan merangkumkan perubahan, kami mengasingkan bahagian sistem yang stabil daripada bahagian yang mudah diubah Semasa evolusi sistem, kami hanya perlu menggantikan bahagian yang mudah diubah jika bahagian ini telah dikapsulkan Ya, ia agak mudah untuk diganti. Ini boleh memastikan kestabilan dan kebolehskalaan program pada tahap yang terbaik.

Terdapat tiga mod asas pengkapsulan JavaScript:

1 Gunakan prinsip keutamaan perjanjian, dan semua pembolehubah persendirian bermula dengan _

 <script type="text/javascript">
  /**
   * 使用约定优先的原则,把所有的私有变量都使用_开头
   */
  var Person = function (no, name, age)
  {
   this.setNo(no);
   this.setName(name);
   this.setAge(age);
  }
  Person.prototype = {
   constructor: Person,
   checkNo: function (no)
   {
    if (!no.constructor == "string" || no.length != 4)
     throw new Error("学号必须为4位");
   },
   setNo: function (no)
   {
    this.checkNo(no);
    this._no = no;
   }, 
   getNo: function ()
   {
    return this._no;
   setName: function (name)
   {
    this._name = name;
   }, 
   getName: function ()
   {
    return this._name;
   }, 
   setAge: function (age)
   {
    this._age = age;
   }, 
   getAge: function ()
   {
    return this._age;
   }, 
   toString: function ()
   {
    return "no = " + this._no + " , name = " + this._name + " , age = " + this._age;
   }
  };
  var p1 = new Person("0001", "小平果", "22");
  console.log(p1.toString());  //no = 0001 , name = 小平果 , age = 22
  p1.setNo("0003");
  console.log(p1.toString());  //no = 0003 , name = 小平果 , age = 22
  p1.no = "0004";
  p1._no = "0004";
  console.log(p1.toString()); //no = 0004 , name =小平果 , age = 22

 </script>

Setelah membaca kod, adakah anda merasa seperti telah ditipu jika anda meletakkan semua pembolehubah yang bermula dengan _, ia masih boleh diakses secara langsung. Sudah tentu, ini dikatakan perjanjian diutamakan.

Penggunaan garis bawah ini ialah konvensyen penamaan yang terkenal, yang menunjukkan bahawa harta adalah hanya untuk kegunaan dalaman objek, dan mengaksesnya atau menetapkannya secara langsung boleh membawa kepada akibat yang tidak dijangka. Ini membantu menghalang pengaturcara daripada menggunakannya secara tidak sengaja, tetapi ia tidak menghalangnya daripada digunakan secara sengaja.

Kaedah ini masih bagus Sekurang-kurangnya kaedah getter dan setter pembolehubah ahli berada dalam prototaip, bukan dalam objek Secara keseluruhan, ia adalah pilihan yang baik. Jika anda merasakan bahawa ini tidak mungkin dan enkapsulasi mesti dilaksanakan dengan ketat, maka lihat kaedah kedua.

2. Laksanakan enkapsulasi dengan ketat

<script type="text/javascript">
  /**
   * 使用这种方式虽然可以严格实现封装,但是带来的问题是get和set方法都不能存储在prototype中,都是存储在对象中的
   * 这样无形中就增加了开销
   */
  var Person = function (no, name, age)
  {
   var _no , _name, _age ;
   var checkNo = function (no)
   {
    if (!no.constructor == "string" || no.length != 4)
     throw new Error("学号必须为4位");
   };
   this.setNo = function (no)
   {
    checkNo(no);
    _no = no;
   };
   this.getNo = function ()
   {
    return _no;
   }
   this.setName = function (name)
   {
    _name = name;
   }

   this.getName = function ()
   {
    return _name;
   }

   this.setAge = function (age)
   {
    _age = age;
   }
   this.
     getAge = function ()
   {
    return _age;
   }

   this.setNo(no);
   this.setName(name);
   this.setAge(age);
  }
  Person.prototype = {
   constructor: Person,
   toString: function ()
   {
    return "no = " + this.getNo() + " , name = " + this.getName() + " , age = " + this.getAge();
   }
  }
  ;
  var p1 = new Person("0001", "小平果", "22");
  console.log(p1.toString());  //no = 0001 , name =小平果 , age = 22
  p1.setNo("0003");
  console.log(p1.toString());  //no = 0003 , name = 小平果 , age = 22
  p1.no = "0004";
  console.log(p1.toString()); //no = 0003 , name = 小平果 , age = 22

 </script>

Jadi, bagaimanakah ini berbeza daripada mod lain untuk mencipta objek yang telah kita bincangkan sebelum ini Dalam contoh di atas, kita sentiasa menggunakan kata kunci ini apabila membuat dan merujuk sifat sesuatu objek. Dalam contoh ini, kami mengisytiharkan pembolehubah ini dengan var. Ini bermakna mereka hanya wujud dalam pembina Orang. Fungsi checkno diisytiharkan dengan cara yang sama dan oleh itu menjadi kaedah peribadi.

Kaedah yang perlu mengakses pembolehubah dan fungsi ini hanya perlu diisytiharkan secara peribadi. Kaedah ini dipanggil kaedah istimewa kerana ia adalah awam tetapi mempunyai akses kepada harta dan kaedah persendirian. Untuk mengakses fungsi istimewa ini dari luar objek, ia didahului oleh kata kunci ini. Oleh kerana kaedah ini ditakrifkan dalam skop pembina Orang, mereka mempunyai akses kepada harta persendirian. Sifat ini dirujuk tanpa menggunakan kata kunci ini kerana ia bukan umum. Semua kaedah pengambil dan penyerah telah ditukar untuk merujuk sifat ini secara langsung tanpa ini.

Sebarang kaedah yang tidak memerlukan akses terus ke harta persendirian boleh diisytiharkan dalam Person.prototype seperti asalnya. Seperti kaedah toString(). Hanya kaedah yang memerlukan akses terus kepada ahli persendirian harus direka bentuk sebagai kaedah istimewa. Tetapi terlalu banyak kaedah istimewa mengambil terlalu banyak memori, kerana setiap contoh objek mengandungi salinan baharu semua kaedah istimewa.

Lihat kod di atas, nama atribut ini telah dialih keluar, dan pembolehubah ahli hanya boleh diakses melalui pengambil dan penyetel. Namun, terdapat masalah. yang meningkatkan daya ingatan.

3. Dikapsulkan dalam penutup

<script type="text/javascript">

  var Person = (function ()
  {
   //静态方法(共享方法)
   var checkNo = function (no)
   {
    if (!no.constructor == "string" || no.length != 4)
     throw new Error("学号必须为4位");
   };
   //静态变量(共享变量)
   var times = 0;

    //return the constructor.
   return function (no, name, age)
   {
    console.log(times++); // 0 ,1 , 2
    var no , name , age; //私有变量
    this.setNo = function (no) //私有方法
    {
     checkNo(no);
     this._no = no;
    };
    this.getNo = function ()
    {
     return this._no;
    }
    this.setName = function (name)
    {
     this._name = name;
    }

    this.getName = function ()
    {
     return this._name;
    }

    this.setAge = function (age)
    {
     this._age = age;
    }
    this.getAge = function ()
    {
     return this._age;
    }

    this.setNo(no);
    this.setName(name);
    this.setAge(age);
   }
  })();

  Person.prototype = {
   constructor: Person,
   toString: function ()
   {
    return "no = " + this._no + " , name = " + this._name + " , age = " + this._age;
   }
  };

  var p1 = new Person("0001", "小平果", "22");
  var p2 = new Person("0002", "abc", "23");
  var p3 = new Person("0003", "aobama", "24");


  console.log(p1.toString());  //no = 0001 , name = 小平果 , age = 22
  console.log(p2.toString());  //no = 0002 , name = abc , age = 23
  console.log(p3.toString()); //no = 0003 , name = aobama , age = 24

 </script>

Kod di atas, selepas enjin js dimuatkan, akan terus melaksanakan fungsi Person = pelaksanaan segera, dan kemudian fungsi ini mengembalikan sub-fungsi, iaitu pembina yang dipanggil oleh Orang baru, dan kerana sub-fungsi itu mengekalkan Rujukan kepada checkNo(no) dan masa dalam fungsi pelaksanaan serta-merta (penutupan yang jelas), jadi semakNo dan masa adalah biasa kepada semua objek Orang Selepas mencipta tiga objek, masa masing-masing adalah 0, 1 dan 2. Kelebihan pendekatan ini ialah kaedah dan sifat yang perlu digunakan semula dalam Orang boleh dijadikan peribadi dan dikongsi antara objek.

ahli persendirian dan ahli istimewa di sini masih diisytiharkan dalam pembina. Tetapi pembina telah berubah daripada fungsi biasa kepada fungsi sebaris, dan diberikan kepada Pembolehubah Orang sebagai nilai pulangan bagi fungsi yang mengandunginya. Ini mewujudkan penutupan di mana anda boleh mengisytiharkan ahli peribadi statik. Sepasang kurungan kosong yang terletak selepas pengisytiharan fungsi luar adalah sangat penting Fungsinya adalah untuk melaksanakan fungsi sebaik sahaja kod dimuatkan. Nilai pulangan fungsi ini ialah fungsi lain, yang diberikan kepada pembolehubah Orang, jadi Orang menjadi pembina. Fungsi dalaman ini dipanggil apabila menginstant Orang. Fungsi luar hanya digunakan untuk membuat penutupan yang boleh digunakan untuk menyimpan ahli statik.

Dalam contoh ini, checkno direka bentuk untuk menjadi kaedah statik kerana tidak masuk akal untuk menjana salinan baharu kaedah ini untuk setiap tika Orang. Terdapat juga masa atribut statik, yang fungsinya adalah untuk menjejaki jumlah panggilan kepada pembina Orang .

Di atas adalah keseluruhan kandungan artikel ini, saya harap ia dapat membantu kajian semua.

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn