享元是意译,英文为 flyWeigth。fly 苍蝇 weight 重量 = 轻量

享元可以理解为通用的属性和元方法,即通过共享属性的方式来达到减少创建对象的目的。从而提升性能优化。

例子

  1. // 100 套衣服,男女各 50 套衣服 进行拍照
  2. var Modal = function(sex, clothes) {
  3. this.sex = sex;
  4. this.clothes = clothes;
  5. }
  6. Modal.prototype.takePhoto = function() {
  7. console.log("sex =" + this.sex + "衣服:" + this.clothes);
  8. }
  9. for (var i = 0; i < 50; i++) {
  10. var modal = new Modal("male", "clothes" + i); // 实现了 50 个男模特
  11. modal.takePhoto();
  12. }
  13. for (var j = 0; j < 50; j++) {
  14. var modal = new Modal("female", "clothes" + j); // 实现了 50 个女模特
  15. modal.takePhoto();
  16. }
  17. // --------------------------------------------------------------
  18. var Modal = function(sex) {
  19. this.sex = sex;
  20. }
  21. Modal.prototype.takePhoto = function() {
  22. console.log("sex =" + this.sex + "衣服:" + this.clothes);
  23. }
  24. var maleModal = new Modal("male");
  25. var femaleModal = new Modal("female");
  26. for (var i = 0; i < 50; i++) {
  27. maleModel.clothes = i; // 问题在于这种赋值相当隐晦,表意不明显。
  28. // 以为是普通对象,实则是实例对象
  29. // 动态增加外部状态
  30. maleModel.takePhoto();
  31. }
  32. for (var j = 0; j < 50; j++) {
  33. femaleModel.clothes = j;
  34. femaleModel.takePhoto();
  35. }

享元模式

解决上面的两个问题,使其有控制。

  1. var Modal = function(sex) {
  2. this.sex = sex;
  3. }
  4. Modal.prototype.takePhoto = function() {
  5. console.log("sex =" + this.sex + "衣服" + this.clothes);
  6. }
  7. var modeFactory = (function() {
  8. var modalGender = {};
  9. // 单例模式,保证一个性别只有一个实例对象
  10. return {
  11. createModel: function(sex) {
  12. if(modalGender[sex]) {
  13. return modalGender[sex];
  14. }
  15. return (modalGender[sex] = new Modal(sex));
  16. }
  17. };
  18. })();
  19. // 状态管理器
  20. var ModalManager = (function() {
  21. const modalObj = {};
  22. return {
  23. add: function(sex, i) {
  24. modalObj[i] = {
  25. clothes: "衣服:" + i
  26. };
  27. },
  28. setExternalState: function(modal, i){
  29. modal.clothes = modalObj[i].clothes;
  30. }
  31. };
  32. })();
  33. for (var i = 0; i < 50; i++) {
  34. var maleModal = ModalManager.add("male", i);
  35. ModalManager.setExternalSate(maleModal, i);
  36. maleModal.takePhoto();
  37. }
  38. for (var i = 0; i < 50; i++) {
  39. var femaleModal = ModalManager.add("female", i);
  40. ModalManager.setExternalSate(femaleModal, i);
  41. femaleModal.takePhoto();
  42. }