从原型函数JavaScript访问对象上下文

时间:2016-10-28 07:15:55

标签: javascript jquery class design-patterns prototype-programming

我对象范围有问题。

这是我的班级代码

// Table list module
        function DynamicItemList(data, settings, fields) {
            if (!(this instanceof DynamicItemList)) {
                return new DynamicItemList(data, settings, fields);
            }
            this.data = data;
            this.settings = settings;
            this.fields = fields;
            this.dataSet = {
                "Result": "OK",
                "Records": this.data ? JSON.parse(this.data) : []
            };
            this.items = this.dataSet["Records"];
            this.generateId = makeIdCounter(findMaxInArray(this.dataSet["Records"], "id") + 1);
            this.dataHiddenInput = $(this.settings["hidden-input"]);
        }

        DynamicItemList.RESULT_OK = {"Result": "OK"};
        DynamicItemList.RESULT_ERROR = {"Result": "Error", "Message": "Error occurred"};
        DynamicItemList.prototype = (function () {
            var _self = this;
            var fetchItemsList = function (postData, jtParams) {
                return _self.dataSet;
            };
            var createItem = function (item) {
                item = parseQueryString(item);
                item.id = this.generateId();
                _self.items.push(item);
                return {
                    "Result": "OK",
                    "Record": item
                }
            };
            var removeItem = function (postData) {
                _self.items = removeFromArrayByPropertyValue(_self.items, "id", postData.id);
                _self.dataSet["Records"] = _self.items;
                _self.generateId = makeIdCounter(findMaxInArray(_self.dataSet["Records"], "id") + 1);
                return DynamicItemList.RESULT_OK;
            };
            return {
                setupTable: function () {
                    $(_self.settings["table-container"]).jtable({
                        title: _self.settings['title'],
                        actions: {
                            listAction: fetchItemsList,
                            deleteAction: removeItem
                        },
                        fields: _self.fields
                    });
                },
                load: function () {
                    $(_self.settings['table-container']).jtable('load');
                },
                submit: function () {
                    _self.dataHiddenInput.val(JSON.stringify(_self.dataSet["Records"]));
                }
            };
        })();

我在访问对象字段时遇到问题。

我尝试使用self维护调用范围。但是因为它首先从全局范围初始化,所以我将Window对象保存在_self中。

如果_self只使用this,它也不起作用。因为我可以猜测我的函数fetchItemsList是从jTable上下文调用的,而不是指向Window对象,所以我得到错误undefined

我尝试过不同的方法,但都没有。

请建议我该如何解决这个问题。

THX。

更新

以下是将所有方法公开为公开的版本。

            // Table list module
        function DynamicItemList(data, settings, fields) {
            if (!(this instanceof DynamicItemList)) {
                return new DynamicItemList(data, settings, fields);
            }
            this.data = data;
            this.settings = settings;
            this.fields = fields;
            this.dataSet = {
                "Result": "OK",
                "Records": this.data ? JSON.parse(this.data) : []
            };
            this.items = this.dataSet["Records"];
            this.generateId = makeIdCounter(findMaxInArray(this.dataSet["Records"], "id") + 1);
            this.dataHiddenInput = $(this.settings["hidden-input"]);
        }

        DynamicItemList.RESULT_OK = {"Result": "OK"};
        DynamicItemList.RESULT_ERROR = {"Result": "Error", "Message": "Error occurred"};
        DynamicItemList.prototype.fetchItemsList = function (postData, jtParams) {
            return this.dataSet;
        };
        DynamicItemList.prototype.createItem = function (item) {
            item = parseQueryString(item);
            item.id = this.generateId();
            this.items.push(item);
            return {
                "Result": "OK",
                "Record": item
            }
        };
        DynamicItemList.prototype.setupTable = function () {
            $(this.settings["table-container"]).jtable({
                title: this.settings['title'],
                actions: this,
                fields: this.fields
            });
        };
        DynamicItemList.prototype.load = function () {
            $(this.settings['table-container']).jtable('load');
        };
        DynamicItemList.prototype.submit = function () {
            this.dataHiddenInput.val(JSON.stringify(this.dataSet["Records"]));
        };
        DynamicItemList.prototype.removeItem = function (postData) {
            this.items = removeFromArrayByPropertyValue(this.items, "id", postData.id);
            this.dataSet["Records"] = this.items;
            this.generateId = makeIdCounter(findMaxInArray(this.dataSet["Records"], "id") + 1);
            return DynamicItemList.RESULT_OK;
        };
        DynamicItemList.prototype.updateItem = function (postData) {
            postData = parseQueryString(postData);
            var indexObjToUpdate = findIndexOfObjByPropertyValue(this.items, "id", postData.id);
            if (indexObjToUpdate >= 0) {
                this.items[indexObjToUpdate] = postData;
                return DynamicItemList.RESULT_OK;
            }
            else {
                return DynamicItemList.RESULT_ERROR;
            }

        };

3 个答案:

答案 0 :(得分:0)

您将函数直接分配给原型。 DynamicItemList.prototype=通常它的格式为DynamicItemList.prototype.somefunc=

答案 1 :(得分:0)

感谢大家的帮助,我刚刚想出问题出在哪里。

对于将方法公开为公开的最新版本。 问题部分是

   $(this.settings["table-container"]).jtable({
                    title: this.settings['title'],
                    actions: {
                        listAction: this.fetchItemsList,
                        createAction: this.createItem,
                        updateAction: this.updateItem,
                        deleteAction: this.removeItem
                    },
                    fields: this.fields
                });
            };

这里创建了一个新对象,它不知道正在创建对象的变量。

我已将代码更改为以下内容,如上所示。

  $(this.settings["table-container"]).jtable({
                title: this.settings['title'],
                actions: this,
                fields: this.fields
            });

现在它就像一个魅力。如果这种方法有缺点,请告诉我。 我的问题最初是在这一部分,保持方法私有没有任何意义,因为我的对象被另一个库使用。

大家好。

答案 2 :(得分:0)

您需要使原型方法使用this关键字(以便它们动态地接收它们被调用的实例),但您需要bind the instance in the callbacks传入jtable

DynamicItemList.prototype.setupTable = function () {
    var self = this;
    function fetchItemsList(postData, jtParams) {
        return self.dataSet;
    }
    function createItem(item) {
        item = parseQueryString(item);
        item.id = self.generateId();
        self.items.push(item);
        return {
            "Result": "OK",
            "Record": item
        };
    }
    … // other callbacks

    $(this.settings["table-container"]).jtable({
        title: this.settings['title'],
        actions: {
            listAction: fetchItemsList,
            createAction: createItem,
            updateAction: updateItem,
            deleteAction: removeItem
        },
        fields: this.fields
    });
};