2014-02-06 7 views
2

Я пытаюсь использовать: Simple Javascript Inheritance by John ResigПростой JavaScript Наследование с переменными экземпляра

Что я нахожу очень ограниченным является тот факт, что переменные не являются частными к экземпляру объекта. Этот простой факт является одним из ключевых факторов, для которого человек решил бы принять такой подход.

Я видел в комментариях в связанных страницах, что кто-то предполагая следующее:

init: function() { 
    // Private var 
    var _div = $(div); 
    // Priviledged method accesses private var 
    this.getDiv = function() { return _div; } 
    this.setDiv = function (div) { _div = div; } 
    // other initialization stuff 
} 

У меня есть некоторые сомнения по поводу такого подхода:

  1. В классе я объявляющий , мне нужно будет всегда обращаться к этим переменным через setter и getter?
  2. Как я могу использовать эти переменные в определении внутренних функций?

Допустим, например:

node.append("title").text(function(d) { /* use private variable */ }); 

Кто-то преодолел это ограничение?

Спасибо и наилучшими пожеланиями

Sergio

ответ

0

Javascript действительно не делает частные переменные экземпляра очень хорошо. Можно подстроить, но это волосатое. Чтобы действительно это сделать, вы должны создать все свои методы в инициализаторе.

var Foo = function() { 
    var bar = 9; 

    this.squarePrivate = function() { 
    return bar * bar; 
    }; 
} 

new Foo().squarePrivate() //=> 81 

Это означает, что каждая функция должна быть создана в рамках конструктора экземпляра, поэтому он имеет доступ к этому местному Варсу. Так что экземпляры объектов медленнее.

Если вы используете подход на основе класса или прототипа, как вы это делаете, вы не можете действительно хорошо выполнять частные переменные экземпляра.

Использование методов getter/setter, созданных в конструкторе, может работать, но эти геттеры и сеттеры являются общедоступными, поэтому он не позволит вам скрыть значение, а только обернуть его get и установить с помощью логики. Если вы держите геттер и сеттер, как вы их, нет смысла делать их частными.

Общим соглашением является префикс частной собственности с подчеркиванием, который говорит людям, чтобы они не возились с ним. Но если выявление данных является проблемой безопасности, это, очевидно, плохая идея.

init: function() { 
    this._bar = 9; // people will see instance._bar, but get the hint not to touch 
}, 
squarePrivate: function() { 
    return this._bar * this._bar; 
} 

Но ответ на ваши вопросы:

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

Да. Только функция init имеет доступ к локальной переменной, поэтому функции setter и getter, созданные в этой области, также могут получить доступ к этой локальной переменной. Но эта локальная переменная не будет доступна в другом месте, поэтому вы должны использовать геттеры/сеттеры.

Как использовать эти переменные в определении внутренних функций?

Ну вот и вся проблема. Если вы используете общественные геттеры, вызовите их, но это означает, что данные эффективно открыты. Или, если вы поедете с моим первым примером, просто обратитесь к локальному var. Или, если вы используете подчеркнутое свойство, просто обратитесь к нему.

0

Прежде всего спасибо Alex за ваш добрый ответ. Мне потребовалось некоторое время, чтобы переварить все, что вы, хотя я.

Я хочу ответить на мой вопрос, хотя у меня были особые потребности, и я не чувствую, что вопрос был хорошо поставлен вначале.

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

Я на самом деле сделал несколько тестов, и убедился, что переменные, объявленные в методе инициализации, как это:

this._instanceVar 

фактически принадлежат самому экземпляру. В других методах, объявленных в классе, я могу получить к ним доступ, просто ссылаясь на них так.

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

, например:

var Person = Class.extend({ 
    init: function() { 
     this._name; 
    }, 
    printNameOnClick: function() { 
     var thiz = this; 
     document.getElementById('nameDiv').addEventListener("click", function() { 
      document.getElementById('nameDiv').innerHTML = thiz.name; 
     }); 
    } 
} 

Или whaterver.

Все это было связано с тем, что он должен был династически синхронизировать экземпляр определенного объекта, на котором можно было бы вызвать один метод. Иерархическая модель позволяет мне быть уверенным, что в списке будет вызвана функция в верхнем классе.

С наилучшими пожеланиями,

Sergio