Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/459.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于在Javascript函数上创建良好接口的问题_Javascript_Class Design_Code Complete - Fatal编程技术网

关于在Javascript函数上创建良好接口的问题

关于在Javascript函数上创建良好接口的问题,javascript,class-design,code-complete,Javascript,Class Design,Code Complete,如何在一些Javascript代码上实现?例如,在这种情况下: $('#variable').on('click', function(){ //do some stuff }); 这是一个非常常见的代码段,但它将函数作为参数传递给另一个函数。在我看来,它们不是自我记录的(它是不可读的),并且不维护书中所指出的程序抽象;但是非常常见。您可以将要传递的函数分配给局部变量,这样至少可以给它一个名称: var onClickCallback = f

如何在一些Javascript代码上实现?例如,在这种情况下:

$('#variable').on('click', function(){
                          //do some stuff
});

这是一个非常常见的代码段,但它将函数作为参数传递给另一个函数。在我看来,它们不是自我记录的(它是不可读的),并且不维护书中所指出的程序抽象;但是非常常见。

您可以将要传递的函数分配给局部变量,这样至少可以给它一个名称:

var onClickCallback = function() {
                      //do some stuff
};

$('#variable').on('click', onClickCallback);

假设DOM节点
#变量
是调用服务并在单击时添加CSS类“clicked”的“widget”UI元素的根

以下代码演示了单一责任原则、模型-视图-控制器、依赖项注入、有意义的命名、适当的文档、无全局变量、数据封装、高内聚、低耦合等:

/**
 * Responsible for performing some
 * significant action(s) related to
 * widgets.
 */
function WidgetService() {}

WidgetService.prototype.doSomething = function() {
    //do some stuff
};

/**
 * Responsible for wiring up the object
 * graph backing the widget.
 */
function WidgetController($, widgetService) {
    this._service = widgetService;
    this._model = new WidgetModel({
        renderCb: renderCb.bind(this)
    });
    this._view = new WidgetView($, this._model);

    this.onClick = this._onClick.bind(this);

    function renderCb() {
        this._view.render();
    }
}

WidgetController.prototype._onClick = function() {
    this._service.doSomething();
    this._model.isClicked = true;
};

/**
 * Responsible for encapsulating the
 * state of the UI element.
 */
function WidgetModel(options) {
    options = options || {
        renderCb: noop
    };

    this._renderCb = options.renderCb;
}

WidgetModel.prototype = {
    _isClicked: false,

    get isClicked() {
        return this._isClicked;
    },

    set isClicked(value) {
        this._isClicked = value;
        this._renderCb(this._isClicked);
    }
};

/**
 * Responsible for interacting with the DOM.
 */
function WidgetView($, model) {
    this._$ = $;
    this._model = model;

    this.render = this._render.bind(this);
}

WidgetView.prototype.el = '#variable';

WidgetView.prototype._render = function() {
    this._$(this.el).addClass(this._model.isClicked ? 'clicked' : '');
};

/**
 * Responsible for linking the DOM
 * event with the controller.
 */
function WidgetRouter($, controller) {
    $(WidgetView.prototype.el).on('click', controller.onClick);
}

function noop() {}

$(function() {
    // Go...
    var s, c, r;

    s = new WidgetService();
    c = new WidgetController($, s);
    r = new WidgetRouter($, c);

    // Now clicking on the element with ID '#variable' will add a class of clicked to it.  
});

大多数人可能手头没有这本书,所以你必须提供一个非付费链接,或者自己解释他们所说的“高质量的日常工作”是什么意思。对我来说,这听起来像是一个Java程序员的困惑,他无法理解高阶函数或lambda函数。这门语言给了你很多束缚自己的绳索,因此你必须比其他语言更加小心和自律。您可以而且可能应该做的一件事是将要传递的函数赋给一个局部变量,这样您至少可以命名它。我不会仅仅为了得到一个定义而阅读20页。@bhspencer不同意。你可以用任何语言编写好的代码。JavaScript在这方面比C++、java、VB、C++等都不坏。请看我的答案。很明显,这是一次点击回调。此外,您还可以命名内联函数!有助于实现更好的堆栈跟踪(您的代码对这些跟踪没有帮助),但它是可测试的。你不能测试匿名函数,因为你没有对它的引用。如果一个函数的唯一引用位于代码中某个随机位置的局部变量中,你将如何测试它?这对我来说有点可读性。但我认为在某些情况下,您必须在另一个函数的参数中声明一个函数。那么,在这种情况下,我能做些什么来维护良好的接口呢?我不认为有必要使用匿名函数作为参数。托德的座右铭在这里写了一篇关于这个主题的文章,你可能会觉得很有趣:哈哈!对于更改单个DOM元素的类来说,确实有些过分了。但是从什么时候起,职业发展就这么简单了?这段代码是可维护和可测试的。