Javascript, внутренние классы и как эффективно обращаться к родительской области видимости - PullRequest
7 голосов
/ 22 января 2011

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

Какой-то код покажет, что я имею в виду.Предположим, я определил класс MyType1, который предоставляет несколько свойств и одну функцию, SayHello:

(function(){
    MyType1 = function(name){
        this.TypeName = "MyType1";
        this.Name = name;
    };

    MyType1.prototype.SayHello = function() {
        say(this.Name + " says hello...");
    };
})();

Хорошо, теперь, начиная с этого момента, я хочу добавить «внутренний класс» в MyType1, поэтомуЯ добавляю новый код, чтобы он выглядел так:

(function(){
    MyType1 = function(name){
        this.TypeName = "MyType1";
        this.Name = name;
        var parentName = name;
        this.Child = function(name) {
            this.Description = parentName + "'s child, " + name;
        };

        this.Child.prototype.Introduce = function() {
            say(this.Description + ", greets you...");
        };
    };

    MyType1.prototype.SayHello = function() {
        say(this.Name + " says hello...");
    };
})();

Теперь я могу использовать эти классы так:

var x = new MyType1("Victor");
x.SayHello();

var c = new x.Child("Elizabeth");
c.Introduce();

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

(function(){
    MyType2 = function(name){
        this.TypeName = "MyType2";
        this.Name = name;
        this.Prop1 = 1872;
        var parentName = name;
    };

    MyType2.prototype.SayHello = function() {
        say(this.Name + " says hello...");
    };

    var c1 = function(name) {
        this.Description = parentName + "'s child, " + name;
        //                ^^ no go! ^^
    };

    c1.prototype.Introduce = function() {
        say(this.Description + ", greets you...");
    };

    MyType2.prototype.Child = c1;

})();

Но это не работает.Разумеется, parentName var находится вне области видимости.

Существует ли эффективный способ для экземпляра Child (в конструкторе или в любой функции класса) получить доступ к родительскому экземпляру (MyType2)?


Я знаю, что мог бы определить класс Child как независимый, не вложенный класс, а затем в ctor просто передать экземпляр Parent.Но это создает N ссылок на родительский экземпляр, по одной на каждый экземпляр Child.Это кажется неэффективностью, которую я хотел бы избежать.

спасибо за любые советы.


EDIT - причина, по которой я хочу, чтобы Child имел доступ к родительскому экземпляру, состоит в том, что родительский объект содержит объект, которыйсоздать довольно дорого - что-то вроде подключения к базе данных - и я бы хотел, чтобы ребенок мог использовать эту вещь.

Ответы [ 4 ]

3 голосов
/ 22 января 2011

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

Так как каждый «тип» является «объектом» и является изменяемым, вы не получите ничего такого, как усиление эффективности со строгим типом, которое вы могли бы получить от Java или C ++, повторно используя определение одного типа.Думайте о «новом» операторе в javascript как о чем-то вроде «клонировать определение и вызывать конструктор», после чего определение экземпляра все еще может быть изменено.не получит никакой выгоды, если сделает что-то другое.

2 голосов
/ 17 февраля 2014

Вот к чему я пришел через много часов:

var Parent = function() {
  this.name = "Parent";

  this.Child = Child;
  this.Child.prototype.parent = this;
}

var Child = function() {

}

var parent = new Parent();
var child = new parent.Child();

console.log(child.parent.name);

Таким образом, вы можете создать столько родителей, сколько захотите, со своими детьми внизу, и каждый экземпляр Child будет иметь доступ к своему родительскому экземпляру через переменную parent .

1 голос
/ 22 января 2011

Единственный способ, которым я могу думать, - это передать родительский объект в конструктор Child:

MyType2.Child = function (parent, name) {
    this.parent = parent;
    this.name = name;
    this.Description = this.parent.name + "'s child, " + name;
};

И создать его экземпляр с помощью:

var x = new MyType2("Victor");

var c = new MyType2.Child(x, "Elizabeth");

Мое обоснование состоит в том, что онимеет больше смысла в том, что конструктор Child является «статическим» свойством MyType2, вместо экземпляра объекта x в вашем примере, так как здесь речь идет о типах , которые одинаковыво всех случаях MyType2.

0 голосов
/ 27 августа 2014

Я не проверял это, но вы должны иметь возможность использовать JSON для этого:

//code here
var number = {
    real : {
        value : 0, //default value
        rational : {
            integer : {
                isNegative : false,
                value : 0 //default value
            }
        }
    },
    imaginary : {
        //code
    }
};

var number2 = Object.create(number.rational.integer.prototype);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...