Проблема с "этим" в JS - PullRequest
       10

Проблема с "этим" в JS

0 голосов
/ 18 августа 2011

Рассмотрим следующий код:

    var table = function () {

        return {
            _init: function (tableId) {
                this.tableId = tableId;
                this.table = $("#" + tableId);
            },

            removeStripes: function() {
                this.table.find(".alt").removeClass("alt");
            },

            addStripes: function () {
                this.table.find("tbody tr:even").addClass("alt");
            },

            resetStripes: function() {
                this.removeStripes();
                this.addStripes();
            },

            sort: function (options) {
                this.table.tablesorter(options);
                this.table.bind("sortEnd", this.resetStripes);
            },

        }

    }

var newTable = new table();
newTable._init("tableId");
var options = {};
newTable.sort(options);

Браузер говорит, что this.removeStripes, вызываемый this.resetStripes в одной из последних строк), не является функциейЯ предполагаю, что есть какая-то ошибка с this, но я не могу понять, где это.Любая идея, кто-нибудь?

Ответы [ 5 ]

0 голосов
/ 18 августа 2011

Попробуйте:

var table = function () {
        var that = this;
        return {
            _init: function (tableId) {
                that.tableId = tableId;
                that.table = $("#" + tableId);
            },

            removeStripes: function() {
                that.table.find(".alt").removeClass("alt");
            },

            addStripes: function () {
                that.table.find("tbody tr:even").addClass("alt");
            },

            resetStripes: function() {
                that.removeStripes();
                that.addStripes();
            },

            sort: function (options) {
                that.table.tablesorter(options);
                that.table.bind("sortEnd", that.resetStripes);
            },

        }

    }

var newTable = new table();
newTable._init("tableId");
var options = {};
newTable.sort(options);

Это общий шаблон в JavaScript для сохранения this в другой переменной, чтобы вы могли ссылаться на него в более глубоких вложенных функциях.Поскольку javascript this всегда ссылается либо на глобальный объект, либо на объект this, который был передан функции через .call или .apply, иногда он ненадежен для использования.

0 голосов
/ 18 августа 2011
var table = function (tableId) {

        this.tableId = tableId;
        this.table = $("#" + tableId);

        this.removeStripes= function() {
            this.table.find(".alt").removeClass("alt");
        };

        this.addStripes= function () {
            this.table.find("tbody tr:even").addClass("alt");
        };

        this.resetStripes= function() {
            this.removeStripes();
            this.addStripes();
        };

        this.sort= function (options) {
            this.table.tablesorter(options);
            this.table.bind("sortEnd", this.resetStripes);
        };
}

Использование ключевого слова this в Javascript несколько отличается от использования в других языках. Вышеприведенная версия должна работать (я протестировал ее с jsc, а не в браузере с jQuery). Теперь функция является правильным конструктором, заставляя интерпретатор устанавливать «this» для объекта, который будет создан.

0 голосов
/ 18 августа 2011

Попробуйте удалить запятую (,) после объявления функции сортировки.Это, вероятно, не решит вашу проблему, но будет «скомпилировано» под ie <7. </p>

0 голосов
/ 18 августа 2011

То, что вы ищете, это метод / шаблон конструктора.Теперь, когда вы вызываете один из методов экземпляров объектов (например, newTable.removeStripes ()), контекст (this) устанавливается в newTable.Я полагаю, что вы всегда можете изменить контекст с помощью newTable.removeStripes.call (someOtherTableOrObject), который пригодится во многих случаях.

function Table(tableId) {

    this.tableId = tableId;
    this.table = $("#" + tableId);

    this.removeStripes = function() {
        this.table.find(".alt").removeClass("alt");
    };

    this.addStripes = function () {
        this.table.find("tbody tr:even").addClass("alt");
    };

    this.resetStripes = function() {
        this.removeStripes();
        this.addStripes();
    };

    this.sort = function (options) {
        this.table.tablesorter(options);
        this.table.bind("sortEnd", this.resetStripes);
    };

}

var newTable = new Table("tableId");
var options = {};
newTable.sort(options);
0 голосов
/ 18 августа 2011

Поскольку вы объявляете методы с анонимными функциями, this больше не входит в область действия table.

Вы должны использовать:

 removeStripes: function() {
   // ...
 }.bind(this)

во всех ваших методах.

...