2013-07-25 2 views
3

Я использую простой ООП Джона Ресига Class, который приспособлен для использования «строгого использования» и взято с SO post.
Во всех примерах, которые я вижу использование Class.extend так:Простой JavaScript ООП класс

var MyObj = Class.extend({ 
    init:function(){}, 
    prop: "Property" 
}); 

Но я нашел большой недостаток для меня, чтобы использовать его таким образом - я не могу иметь «частные» переменные, так что я не могу хранить ссылку на this как var $this = this;. Я нашел решение для моего случая, и теперь я с помощью Class.extend в следующим образом:

var MyObj = Class.extend(new function(){ 
    var $this = this; 
    this.init = function(){}; 
    this.prop = "Property"; 
}); 

Все работает в моем случае, но я хочу знать, если есть некоторые вещи, которые могут причинить мне проблемы в долгосрочной перспективе ?
В этом случае мое приложение будет потреблять гораздо больше памяти в браузере?
Какие альтернативные способы я должен реализовать своими потребностями?

Примечание: Мне нужно хранить $ это, потому что я использую в значительной степени события и обратные вызовы, поэтому я хочу передать «оригинальный» this легко иметь доступ ко всем методам и свойствам на объекте.

EDIT: В соответствии с просьбой, это мой пример кода:

(function() { 
    "use strict"; 
    window.QuickPlay = Class.extend(new function() { 
     var $this = this; 

     this.init = function (initData) { 
      $this.elementsToHide.push(initData.el); 
      $(function() { 
       playProcessStart(); 
       Sys.Application.add_load(function() { 
        $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function() { $this.setElementsVisibility(""); }); 
       }); 
       $this.setElementsVisibility("hidden"); 
      }); 
     }; 

     this.elementsToHide = []; 

     this.setElementsVisibility = function (visibility) { 
      $.each($this.elementsToHide, function (i) { 
       $("#" + this).css("visibility", visibility); 
      }); 
     }; 
    }); 
}()); 
+3

Ouch, no. Я вряд ли могу поверить, что это действительно работает для вас. Пожалуйста, покажите нам, как вы используете этот «класс» с событиями и обратными вызовами; возможно, разместите свой фактический код (по крайней мере, методы, которые включают '$ this'). – Bergi

+0

@ Bergi я добавил пример - это действительно работает, код уже прошел этап QA :) –

+0

Внутри любого объекта вы должны иметь возможность получить доступ к 'this', который будет привязан к текущему объекту. – travis

ответ

1

Я не могу иметь "частный" переменные

Конечно, вы можете , Либо в (в настоящее время ненужной) (function() { … }()); обертке, либо в вашем конструкторе (init вещь).

new function() { 

Avoid that pattern! Если вам действительно нужен код, чтобы работать, как сейчас, использовать

(function() { 
    "use strict"; 
    // Here's the place where you could put a private, static variable 
    // for example `var elementsToHide = [];` 
    var $this = { 
     init: function (initData) { 
      $this.elementsToHide.push(initData.el); 
      $(function() { 
       playProcessStart(); 
       Sys.Application.add_load(function() { 
        $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function() { 
         $this.setElementsVisibility(""); 
        }); 
       }); 
       $this.setElementsVisibility("hidden"); 
      }); 
     }, 
     elementsToHide: [], 
     setElementsVisibility: function (visibility) { 
      $.each($this.elementsToHide, function (i) { 
       $("#" + this).css("visibility", visibility); 
      }); 
     } 
    }; 
    window.QuickPlay = Class.extend($this); 
}()); 

Я хочу знать, если есть некоторые вещи, которые могут причинить мне проблемы

Да. Несколько экземпляров вряд ли сработают, так как все они ссылаются на тот же массив elementsToHide. И вы не используете какие-либо методы экземпляра (только конструктор и статические элементы на вашем классе), поэтому шаблон класса кажется совершенно ненужным. Вместо этого используйте a module.Если вам нужны отдельные экземпляры (и классы), код должен выглядеть следующим образом:

"use strict"; 

window.QuickPlay = Class.extend({ 
    init: function (initData) { 
     var $this = this; 
     this.elementsToHide = []; 
     $(function() { 
      playProcessStart(); 
      $this.elementsToHide.push(document.getElementById(initData.el)); 
      Sys.Application.add_load(function() { 
       $find("ctl00_ContentPlaceHolderMain_ctrlPlayPopup1").add_closed(function() { 
        $this.setElementsVisibility(""); 
       }); 
      }); 
      $this.setElementsVisibility("hidden"); 
     }); 
    }, 
    setElementsVisibility: function (visibility) { 
     $(this.elementsToHide).css("visibility", visibility); 
    } 
}); 
+0

Спасибо, что указали мне на «огромную» проблему, так как я использую класс ... В моем приложении мне нужно будет использовать «синглтоны» и «Классы», поэтому мне кажется, что мне нужно будет использовать/create два разных шаблона для каждого из случаев. В настоящее время я только начал с JS OOP в проекте, так что еще не поздно изменить все это :) –

+0

Можете ли вы указать мне, пожалуйста, на хороший шаблон, как создать «модуль», который нужно инициализировать данными о создании? –

+0

Я бы подумал о модуле синглтона как о довольно статичном, без «творения». Я мог бы подумать, что a) данные закодированы в код модуля; b) модуль извлекает данные из глобального хранилища данных; c) глобальный контроллер «запускает» модуль, вызывая метод «init» с данными как аргументы. См. Статью Османи, которую я связал для шаблонов структуры кода. – Bergi

2

Вы можете использовать модуль шаблон и сохранить все ООП. Такая модель дает вашему коду большую безопасность и лучшую организацию.

//these are namespaces in javascript 
window.project = window.project || {}; //this kind declarations prevents recreate the object 
project.group = project.group || {}; 

//in the line below we can use $ instead jQuery, and use window and document instead ask for the browser every time. 
(function (window, document, $) { 
    "use strict"; 

    project.group.NameOfYourModule = function() { 
     var privateAttribute = true, 
      students = 32, //It's is a best practice declare everything in an unique var. 

      privateMethod = function() { 
       alert('Now I know OOP using jQuery'); 
      }; 

     return { 
      init: function() { 
       //this is a public method and we can initiate some private method; 
       privateMethod(); 

       //we call a public method using this 
       this.publicMethod(); 
      }, 
      publicMethod: function() { 
       //this is a public method 
      } 
     }; 
    }; 

    $(function() { 
     var myclass = new project.group.NameOfYourModule(); //instantiate you class 
     myclass.init(); //initiate some public method 
    }); 
}(window, document, jQuery)); 
  • Рабочий пример на JsFiddle
  • Как работать с Наследственность и модуля Pattern here
+0

Это выглядит красиво, но как насчет наследования? Как в вашем шаблоне я могу создать MySecondModule, который наследует от NameOfYourModule? Класс дает мне это. –

+0

Я добавил ссылку exaplaining, как это работает наследование. Рад помочь :) –

+0

Спасибо, я видел ссылку ... Я уверен, что это сработает, но это слишком сложно для других членов команды :(Я пытаюсь сделать что-то такое простое в использовании ... –

Смежные вопросы