ООП JavaScript - почему объект аргумента не видно из метода экземпляра? - PullRequest
0 голосов
/ 27 декабря 2011

Я создал диалоговые классы jQuery.

Базовый класс AlertDialog .Дочерним классом является ChildAlertDialog .

Когда создается экземпляр ChildAlertDialog, он принимает elementId (идентификатор DOM) и объект executor (экземпляр MyExcecutor) и отображает диалоговое окно с предупреждением с кнопкой закрытия.

Кнопка закрытия вызывает метод экземпляра MyExecutor executeClose();

Но когда я звоню:

alertbox.displayDialog();

, я получаю ошибку:

executor is undefined
executor.executeClose();

Этоработает, если я передаю executor методу displayDialog ().Так что я немного запутался, потому что он работал бы на другом языке, например, на Java, но JavaScript кажется другим.Должен ли я просто передать executor в displayDialog ()?Или есть способ получше?

------ класс диалога ------------

//base class
function AlertDialog(elementId, executor) {
    this.elementId = elementId;
    this.height = null;
    this.width = null;

    this.displayDialog = function() {
        $(this.elementId).dialog({
            autoOpen: true,
            height: this.height,
            width: this.width,
            buttons: {
                'close me': function() {
                    executor.executeClose(); //ERROR HERE!!!!!
                }
            }
        });
}

//child class
function ChildAlertDialog(elementId, executor) {
    this.elementId = elementId;
    this.height = 70;
    this.width = 400;
}

//inheritance
ChildAlertDialog.prototype = new AlertDialog();
ChildAlertDialog.prototype.constructor = ChildAlertDialog;

Класс, который использует класс ChildAlertDialog.

function MyExcecutor() {

    this.execute = function() {
        //passing elementID and MyExecutor object to ChildAlertDialog
        var alertbox = new ChildAlertDialog("#someDiv",this);
        alertbox.displayDialog();
    }

    this.executeClose = function() {
        //do something when the dialog is closed
    }
}

Ответы [ 2 ]

2 голосов
/ 27 декабря 2011

Область действия аргумента функции - только эта функция.Когда вы вызываете конструктор ChildAlertDialog во время создания объекта, executor доступен только в ChildAlertDialog.

Чтобы убедиться, что исполнитель доступен для displayDialog, либо явно вызовите AlertDialog:

function ChildAlertDialog(elementId, executor) {
    AlertDialog.call(this, elementId, executor);
    this.height = 70;
    this.width = 400;
}

или сделайте executor свойством объекта диалога.

function AlertDialog(elementId, executor) {
    this.executor = executor;
    ...

    this.displayDialog = function() {
        ...
                    this.executor.executeClose();
}

//child class
function ChildAlertDialog(elementId, executor) {
    this.executor = executor;
    ...
}

Эта проблема, отсутствие разделения между созданием прототипов и инициализацией объекта , была тем, чтовел Дугласа Крокфорда к разработке Object.create, которая теперь становится стандартной стандартной функцией JS браузера.

function AlertDialog(elementId, executor) {
    this.elementId = elementId;
    this.executor = executor;
}
AlertDialog.prototype.height = null;
AlertDialog.prototype.width = null;
AlertDialog.prototype.displayDialog = function() {
    $(this.elementId).dialog({
        autoOpen: true,
        height: this.height,
        width: this.width,
        buttons: {
            'close me': function() {
                this.executor.executeClose();
            }
        }
    });
};


//child class
function ChildAlertDialog(elementId, executor) {
    AlertDialog.call(this, elementId, executor);
    this.height = 70;
    this.width = 400;
}

//inheritance
ChildAlertDialog.prototype = Object.create(AlertDialog.prototype, 
        {constructor: {value: ChildAlertDialog, writable: false, enumerable: false}});
1 голос
/ 27 декабря 2011

Вы переопределяете функцию конструктора и никогда не вызываете оригинальную версию, которая устанавливает это.Ваша первая функция конструктора, которая связывает executor в области действия экземпляра , на самом деле никогда не запускается .Так что вы должны назвать его, и синтаксис немного странный.

Попробуйте вместо этого, что вызывает оригинальную версию:

//child class
function ChildAlertDialog(elementId, executor) {
    // Run the parent constructor function
    AlertDialog.call(this, elementId, executor);

    // Child class setup.
    this.elementId = elementId;
    this.height = 70;
    this.width = 400;
}

//inheritance
ChildAlertDialog.prototype = new AlertDialog();
ChildAlertDialog.prototype.constructor = ChildAlertDialog;

Вы должны использовать ConstructorFunction.call(this, args...)запустить функцию конструктора на экземпляре.К сожалению, прототипы и функции конструктора наследуются по-разному.И именно поэтому настройка методов экземпляра в конструкторе обычно плохая идея.

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