【问题标题】:Correct structure for "static" type objects in JavascriptJavascript 中“静态”类型对象的正确结构
【发布时间】:2016-08-29 15:11:22
【问题描述】:

我正在努力掌握如何在 JavaScript 中创建“静态”对象类型(我怀疑我的措辞是否正确......)。

在下面的代码中,我试图创建一个 jQuery 插件(不过我怀疑这无关紧要),它创建了多个 CrmQuery,每个都有自己的上下文信息作为 instance 传递。我还想为所有CrmQuery 使用创建一个“静态”对象(它可以是无状态的),并希望将它包含在CrmQuery 命名空间中。

这是我的结构,但是在调用CrmQuery.searchOperator[instance.Operator].buildCondition(instance.fieldName, searchTerm)时,buildCondition函数无法访问CrmQuery.searchOperator中的oDataOperator函数。我尝试过以多种方式引用它,而不仅仅是searchOperator.oDataOperator,而this 是对实际属性的引用,而不是CrmQuery.searchOperator

结构:

(function($) { 
...
var crmQuery = new CrmQuery(instance);
var data = crmQuery.searchCrm(searchTerm);
... 

var CrmQuery = function(instance) {
    ...
    this.oDataUrl = function() {
        ...
        oDataFilter += CrmQuery.searchOperator[instance.Operator].buildCondition(instance.fieldName, searchTerm);
        ...
        return oDataFilter;
    }();

    this.searchCrm(searchTerm) {
        ...
        url += this.oDataUrl;
    }
    ...
}

CrmQuery.searchOperator = {
    oDataFunctionOperator: function oDataFunctionOperator(fieldName, searchTerm, operator) {
        return operator + "(" + fieldName + ", '" + searchTerm + "')";
    },
    oDataOperator: function oDataOperator(fieldName, searchTerm, operator) {
        return fieldName + " " + operator + " '" + searchTerm +"'";
    },
    STARTSWITH: { 
        operator: "startswith", 
        buildCondition: function(fieldName, searchTerm) { 
                return this.oDataFunctionOperator(fieldName, searchTerm, this.operator) 
            }
    },
    ENDSWITH: { 
        operator: "endswith", 
        buildCondition: function(fieldName, searchTerm) { 
                return searchOperator.oDataFunctionOperator(fieldName, searchTerm, this.operator) 
            }
    },
    CONTAINS: { 
        operator: "substringof", 
        buildCondition: function(fieldName, searchTerm) { 
                return searchOperator.oDataFunctionOperator(fieldName, searchTerm, this.operator) 
            }
    },
    EXACTMATCH: { 
        operator: "eq", 
        buildCondition: function(fieldName, searchTerm) { 
                return searchOperator.oDataOperator(fieldName, searchTerm, this.operator) 
            }
    },
    toString: function () {
        var thisVar = this;
        var output = "searchOperator enum. ";
        output += $.map(Object.keys(this), function (i) {
            if (typeof thisVar[i] !== "function") 
                return i + ": " + thisVar[i].operator;
        }).join(", ");
        return output;
    }
}
...
}(jQuery));

在 JavaScript 中实现这样的模式的正确方法是什么?

我希望这是有道理的?抱歉,如果它过于冗长,但我不想遗漏任何可能很重要的内容。

非常感谢, 詹姆斯

【问题讨论】:

    标签: javascript design-patterns properties scope static


    【解决方案1】:

    继承是解决这个问题的一种方法,例如:

    function searchOperator() {
    }
    
    //searchOperator.prototype.toString = ...
    
    functionOperator = function(operator) {
        searchOperator.apply(this);
        this.operator = operator;
    }
    
    functionOperator.prototype = Object.create(searchOperator.prototype);
    
    functionOperator.prototype.buildCondition = function (fieldName, searchTerm) {
        return this.operator + "(" + fieldName + ", '" + searchTerm + "')";
    }
    
    operators = {
    
        STARTSWITH: new functionOperator('startswith')
    }
    
    console.log(operators.STARTSWITH.buildCondition('foo', 'bar'))
    

    【讨论】:

    • 谢谢格奥尔格。我会在CrmQuery 函数中声明所有这些,还是它们会坐在函数之外?另外,我不太了解逻辑 - functionOperator 是否继承自 searchOperator,但添加了 buildCondition 函数?
    • 此外,操作员应该向buildCondition 指示使用哪个函数来构建自己。在您的示例中这是如何完成的,因为您将 buildCondition 作为实际代码,而不是调用运营商特定的函数?
    • searchOperator 是一个抽象类,它不知道如何构建条件。我将STARTSWITH 之类的运算符编码为functionOperator 的实例,但它们也可以是具有特定功能的子类
    猜你喜欢
    • 2015-01-10
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 2012-10-10
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多