Наследование JavaScript - PullRequest
       12

Наследование JavaScript

2 голосов
/ 22 сентября 2010

Если у меня есть объект, который я хочу «наследовать» от «суперобъекта», чтобы обеспечить согласованность. Они будут смешанными переменными. REVISED

ParentObj = function()
{
    var self = this;
    this.interval = null
    this.name = "";
    this.timeout = 1000;

    this.stop = function()
    {
        clearInterval(self.interval);
    };

    this.start = function()
    {
        self.log("Starting up");
        setTimeout(function(){
            self.getData(true);
            self.interval = setInterval(function(){
                self.getData();
            }, self.timeout)
        }, 1000);
    };

    this.log = function(msg)
    {
        require("sys").log(self.name + ": " + msg);
    };

    this.getData = function(override)
    {
        if(override || self.interval)
        {
            /**
            * Allow
            */
            self.log(new Date());
        }
        else
        {
            self.log("Unable to override and no interval");
        }
    }
}

ChildObj = function()
{
    var self = this;
    this.name = "Child";
    this.timeout = 500;
    this.start();
    setTimeout(function(){
        self.stop();
    }, 2000);
}

ChildObj.prototype = new ParentObj();


var c = new ChildObj();

Похоже, это не работает правильно, в частности, он не видит self.interval и не может его очистить.

Я открыт для других методов наследования JavaScript, если они существуют, но мне действительно нужно начать инкапсуляцию содержимого в родительский. Есть три или четыре функции, которые идентичны, но время от времени меняются, и это означает, что мне нужно выполнить дюжину файлов, чтобы внести изменения, а не просто изменить родительский элемент.

Прорабатывая некоторые предложения, я попытался более четко определить, какую функциональность я собираюсь использовать. В идеале все «дети» должны иметь пару уникальных настроек (имя, интервал, настройки конфигурации) и метод getData(), в то время как родительский элемент управляет запуском, остановкой, ведением журнала и всем остальным.

Ответы [ 3 ]

1 голос
/ 22 сентября 2010
  • 'Клонировать' объект, сделав объект прототипом одноразовой функции и вызвав эту функцию с помощью 'new'.

  • Клонировать прототип родительского конструктораи установите результат как прототип дочернего класса.

...

/**
 * Extend a constructor with a subtype
 * @param {Function} superCtor      Constructor of supertype
 * @param {Function} subCtor        Constructor of subtype
 * @return {Function}               Constructor of subtype
 */
var extend = (function(){

  return function (superCtor, subCtor) {
    var oldProto=subCtor.prototype;
    subCtor.prototype=clone(superCtor.prototype);
    return merge(subCtor.prototype, oldProto).constructor=subCtor; 
  }

  function Clone(){}

  /**
   * Clone an object
   * @param {Object}  obj     Object to clone
   * @return {Object}         Cloned object
   */
  function clone (obj) { Clone.prototype=obj; return new Clone() }

  /**
   * Merge two objects
   * @param {Object} dst      Destination object
   * @param {Object} src      Source object
   * @return {Object}         Destination object
   */
  function merge (dst, src) {
    for (var p in src) if (src.hasOwnProperty(p)) dst[p]=src[p];
    return dst;
  }

}());
0 голосов
/ 22 сентября 2010

Используя этот метод наследования, вы можете смешивать только переменные «вверх по течению».Ваш дочерний объект сможет видеть открытые свойства своего прототипа, но прототип не может видеть свойства его дочерних объектов.Он должен быть автономным.

(РЕДАКТИРОВАТЬ: я только что заметил, что вы также используете "self", не объявляя его в sobj.)

sobj = function()
{
    var self = this;
    self.close = function()
    {
        clearInterval(self.interval);
    }

    self.interval = null;
}
cobj = function()
{
    var self = this;
    self.interval = setInterval(function(){ /* Do something */}, 1000);
}
// set cobj.prototype - see explanation below

Как правильно установить прототип(и углубленный взгляд на то, как наследование работает в JS), я отсылаю вас к книге Дугласа Крокфорда JavaScript: хорошие части .

Он действительно написал как правильноустановить прототип на своем сайте.Обязательно используйте версию, которая не касается Object.prototype, так как многие скрипты (jQuery для начинающих) прервутся, если вы измените его.

0 голосов
/ 22 сентября 2010

Во-первых, я не думаю, что var this.interval в порядке.var Ключевое слово используется для определения переменной, но в вашем случае вы ссылаетесь на объект.

Во-вторых, если вы хотите объявить «интервал» как метод вашего cobj, вы должны обернутьтело функции в функции.

Итак, вот так у меня работает:

var sobj = function()
{
    this.close = function()
    {
        clearInterval(this.interval);
    }
}
 var cobj = function()
{   
   this.initInterval = function(){ this.intervalid = setInterval(function(){ alert("test")}, 5000)};
   this.intervalid = null;
}
cobj.prototype = new sobj();

var inst = new cobj();
inst.initInterval();

После того, как я определил функции конструктора, я создаю фактический экземпляр "объект cobj ", а затем вызвать" initInterval "для инициализации" setInterval ".

UPD : обновлен код для комментария @ MooGoo.

...