2015-05-07 119 views
3

我在一个对象上有一系列的链接函数。例如:打破链接功能

var obj = {}; 
obj.a = function(){ 
    console.log('in a'); 
    return this; 
}; 


obj.b = function(){ 
    console.log('in b'); 
    return this; 
}; 

obj.c = function(){ 
    console.log('in c'); 
    return this; 
}; 

obj.a().b().c(); 

显然,结果当我看到控制台:

in a 
in b 
in c 

但我怎么会摆脱这种让ab执行,但从未达到c

+0

如果你写'c()',它将被执行。你可以做一个事情是取代B'的'的返回值'{C:函数(){}}'但是这是令人厌恶的。 –

+0

@OmarElawady会引发错误 – Mark

+0

如果您启动了它,则无法退出该功能。该函数在return语句或其主体结尾处结束。 –

回答

2

显而易见的答案是“只是不要拨打c”,但我想这不是一个选择出于某种原因。

这且不说,你可以破解它周围的c之前从函数调用一个抛出一个错误,但我不会推荐它。例外是错误处理,而不是流量控制[*]。

var obj = {}; 
obj.a = function(){ 
    console.log('in a'); 
    return this; 
}; 


obj.b = function(){ 
    console.log('in b'); 
    if(shouldBreak) { 
     throw new Error('decided to break'); 
    } 

    return this; 
}; 

obj.c = function(){ 
    console.log('in c'); 
    return this; 
}; 

try { 
    obj.a().b().c(); 
} catch { 
    console.log('broke early') 
} 

[*] unless you're into Python

-1

位于a()b()类字段是由c()检查。

0

只需添加你的方法以外的变量,说这就是所谓的标志,默认为真。

你不想经过短短设置标志设置为false待续任何方法。然后在返回之前测试标志。

因此,像:

var flag = true 

function b() { 
    flag = false 
    return this 
} 

function c() { 
    return flag ? this : null 
} 
0

最简单的方法是你打出来的任何函数调用的同样的方式:抛出一个错误。

var obj = { 
    someCondition: false, 

    a: function() { 
     return this; 
    }, 

    b: function() { 
     if (!this.someCondition) { 
      var error = new Error("A message"); 
      error.name = "SomeConditionError"; 
      throw error; 
     } 

     return this; 
    }, 

    c: function() { 
     return this; 
    } 
}; 

然后调用方法并处理错误。

try { 
    obj 
     .a() 
     .b() // throws a "SomeConditionError" here 
     .c(); 
} 
catch (error) { 
    if (error.name == "SomeConditionError") { 
     // gracefully handle "SomeConditionError" 
    } 
    else { 
     // rethrow errors you don't know how to handle gracefully 
     throw error; 
    } 
} 

你想避免的一件事是using exceptions for flow control

如果您需要致电obj.a()然后obj.b(),但后来有条件地obj.c()然后调用代码需要处理:

obj.a().b(); 

if (someCondition) { 
    // Assign to "obj" just in case obj.c() returns a different object 
    obj = obj.c(); 
} 

感觉就像丑陋的代码(和它有点),但这种传达在这些方法调用中引发的任何错误都是灾难性的,显示停止错误。如果你有一个复杂的操作,涉及多个方法调用一个物体或多个物体上,考虑封装在一个“command”:

function DoSomethingCommand(obj) { 
    this.obj = obj; 
} 

DoSomethingCommand.prototype = { 
    constructor: DoSomethingCommand, 

    execute: function() { 
     this.obj.a().b(); 

     if (someCondition) { 
      this.obj = this.obj.c(); 
     } 
    } 
}; 

从调用代码的角度来看,它只是一个简单的调用​​到开始真正复杂的过程:

var command = new DoSomethingCommand(obj); 

command.execute();