功能放置的方法(父母内/外)

时间:2015-04-30 01:17:04

标签: javascript

图表A

用于生成矩形周围的随机点的简单函数

function makeRectanglePointB(box, index){

    /* the `getPoint` function relies on `box` from current scope */
    function getPoint(my_index) {
        switch (my_index) {
            case 0: return new Point(box.p1.x, box.p2.y);
            case 1: return box.p2;
            case 2: return new Point(box.p2.x, box.p1.y);
            case 3: return box.p1;
        }
    }

    var line = new Vector(getPoint(index), getPoint((index + 1) % 4));
    return new Point(randomPoint(line.p1.x, line.p2.x), randomPoint(line.p1.y, line.p2.y));

}

图表B

...或许make getPoint函数仅对传递的参数进行操作...

function makeRectanglePointB(box, index){

    /* keep the `getPoint` function inside the scope where it is used */
    function getPoint(my_box, my_index) {
        switch (my_index) {
            case 0: return new Point(my_box.p1.x, my_box.p2.y);
            case 1: return my_box.p2;
            case 2: return new Point(my_box.p2.x, my_box.p1.y);
            case 3: return my_box.p1;
        }
    }

    var line = new Vector(getPoint(box, index), getPoint(box, (index + 1) % 4));
    return new Point(randomPoint(line.p1.x, line.p2.x), randomPoint(line.p1.y, line.p2.y));

}

/* the `getPoint` function is not accessible here... */

图表C

...或将getPoint功能移到外部范围......

function getPoint(my_box, my_index) {
    switch (my_index) {
        case 0: return new Point(my_box.p1.x, my_box.p2.y);
        case 1: return my_box.p2;
        case 2: return new Point(my_box.p2.x, my_box.p1.y);
        case 3: return my_box.p1;
    }
}

function makeRectanglePointB(box, index){

    var line = new Vector(getPoint(box, index), getPoint(box, (index + 1) % 4));
    return new Point(randomPoint(line.p1.x, line.p2.x), randomPoint(line.p1.y, line.p2.y));

}

/* now the `getPoint` function is accessible here... */

问题

我喜欢显式传递参数,因为它使测试更容易,因为它需要更少的上下文来运行。我也喜欢将它移动到外部范围,因此它明确表示它不依赖于它周围环境中的任何变量,但我真的不喜欢它通常可以从外部范围调用。

组织getPoint功能的最佳方式是什么?

2 个答案:

答案 0 :(得分:0)

展品A和C都很好。如果<body onunload="WriteCookies()" onload="GetCookies()"> 始终不需要额外的参数且可以依赖关闭,那么B没有多大意义。

如果函数依赖于大量范围变量,或者在逻辑上完全链接到该单个函数,则可以使用本地函数。 my_box == box的实现可能随时发生变化,并将makeRectanglePointB作为内部子例程。

如果该功能可能在不同的地方使用,或者由于某些原因需要暴露(白盒测试的可测试性),那么您将使用单独的功能。您不会将其作为公共API的一部分,但将其记录为内部。

答案 1 :(得分:0)

您应该使用构造函数:

var MakeRectanglePointB;
(function(){
function PointB(index, MakeBContext){
  this.parent = MakeBContext;
  this.index = index || MakeBContext.index;
  var b = MakeBContext.box;
  this.get = function(){
    switch(this.index){
      case 0:
        return new Point(b.p1.x, b.p2.y);
      case 1:
        return b.p2;
      case 2:
        return new Point(b.p2.x, b.p1.y);
      case 3:
        return b.p1;
    }
  }
  this.someOtherMethod = function(){
    // code here
    return this; // this access
  }
  this.getMakeRectB = function(){
    // code here
    return MakeBContext; // access to another this
  }
}
MakeRectanglePointB = function(box, index){
  this.box = box; this.index = index;
  this.point = function(idx){
    return new PointB(idx, this);
  }
  this.anotherFunc = function(){
    return 'Well, now.';
  }
}
})();
var mb = new MakeRectanglePointB(box_var, index_var); // replace box_var and index_var
var pb = mb.point();
var line = new Vector(mb.point().get(), mb.point((mb.index + 1) % 4)).get());
console.log(mb.point().someOtherMethod().getMakeRectB().anotherFunc());