2013-03-19 19 views
4
function drawLine(ctx, sX, sY, eX, eY, sRGB, fRGB, lWidth, capStyle) 
{ 
    ctx.beginPath(); 
    ctx.moveTo(sX, sY); 
    ctx.lineTo(eX, eY); 
    ctx.lineWidth = lWidth||5; 
    ctx.strokeStyle = 'rgb(49, 129, 48)'; 
    ctx.lineCap = 'round'; 
    ctx.stroke(); 
    ctx.closePath(); 
} 

然後我要調用的函數是這樣的:如何不通過爭論,仍然使功能的工作?

drawLine(ctx, 50, 50, 100, 100, someStrokeStyle, someFillStyle, someCapStyle); 

正如你可以看到我已經跳過了lWidth參數。即使lWidth未作爲參數傳遞,我也希望該功能仍能正常工作。我將如何做到這一點? Atm,它可能認爲someCapStylelwidth

+0

你錯過了一個參數,這是我看到的參數。我怎麼知道這個lWidth參數 – 999k 2013-03-19 11:07:14

+0

@ 555k是的,當我選擇不給參數時,該函數將如何工作。 – 2013-03-19 11:07:40

+0

您沒有使用參數fRGB和capStyle。所以如果你錯過了一個,那麼函數會被調用capStyle = undefined。你的lWidth值將是一些容易的樣式 – 999k 2013-03-19 11:10:39

回答

3

當你有一個很大的量的參數傳遞到函數像你這樣,使用對象:

function foo({param1: val1, parma2: val2}) {} 

在這種情況下,你不會是取決於對參數的數目以及它們的次序表示。

所以你可以重寫你的函數:

function drawLine(drawObj) 
{ 
    ctx.beginPath(); 
    ctx.moveTo(drawObj.sX, drawObj.sY); 
    ctx.lineTo(drawObj.eX, drawObj.eY); 
    ctx.lineWidth = drawObj.lWidth||5; 
    ctx.strokeStyle = drawObj.sRGB; 
    ctx.lineCap = drawObj.capStyle; 
    ctx.stroke(); 
    ctx.closePath(); 
} 
1

您可以將可選參數放在參數列表的末尾。這樣,如果您將其忽略,其他參數將不會受到影響。

另一種選擇是將單個對象與要定義的屬性一起傳遞,例如

function drawLine(options) { 
    options.ctx.beginPath(); 
    options.ctx.moveTo(options.sX, options.sY); 
    options.ctx.lineTo(options.eX, options.eY); 
    // etc. 
} 
+0

這並不能真正解決問題。如果我沒有在選項對象中指定lWidth,該函數仍然會失敗。我對嗎? – 2013-03-19 11:12:52

+0

是的,但您可以測試它未定義。 – SteveP 2013-03-19 11:14:53

+0

好的。我認爲可能有一個更簡單的方法。但沒關係。感謝你的回答。 – 2013-03-19 11:17:01

2

當你不傳遞任何參數,undefined值傳遞代替,所以只檢查函數的參數是否已經通過與否:

if(typeof argument == "undefined") 
{ 
    argument = "default value"; 
} 

所以不會穿lWidth,只需通過undefined作爲其值

PS最好的方法是使用單個參數args,它將包含所有當前參數作爲屬性的對象。

+0

有沒有辦法完全跳過它,甚至沒有指定未定義? – 2013-03-19 11:15:37

+0

@AnkurSharma是的。使用if(參數) – 999k 2013-03-19 11:19:27

+0

@ 555k但它會認爲lWidth被定義,並且capStyle沒有被定義。你明白我的意思嗎?無論如何,它的確定,我只會使用其他回答者所示的對象。謝謝回答。 – 2013-03-19 11:23:12

2

什麼你想要的是部分評估drawLine函數,爲lWidth分配一個常數值。有一個叫做Jeene的JavaScript庫就是這樣做的。這是你將如何使用它:

function drawLine(ctx, sX, sY, eX, eY, sRGB, fRGB, lWidth, capStyle) { 
    ctx.beginPath(); 
    ctx.moveTo(sX, sY); 
    ctx.lineTo(eX, eY); 
    ctx.lineWidth = lWidth || 5; 
    ctx.strokeStyle = "rgb(49, 129, 48)"; 
    ctx.lineCap = "round"; 
    ctx.stroke(); 
    ctx.closePath(); 
} 

Function.prototype.specialize = net.higherorder.jeene.Jeene.make(); 

var drawLine2 = drawLine.specialize({ 
    lWidth: null // or whatever value you want 
}); 

然後使用drawLine2如下:

drawLine2(ctx, 50, 50, 100, 100, someStrokeStyle, someFillStyle, someCapStyle); 

這就是所謂專業化,是一個非常有用的模式。閱讀更多關於它:A Neighborhood of Infinity: The Three Projections of Doctor Futamura

+0

請問函數自動知道someCapStyle是否是capStyle而不是lWidth。 – 2013-03-19 11:29:20

+0

@AnkurSharma - 是的,它的確如此。這是專業化非常酷的事情。閱讀博客文章,確切知道發生了什麼:http://blog.higher-order.net/2008/09/14/jeene/ – 2013-03-19 11:31:30

+0

如果兩個參數都是字符串類型,該怎麼辦?函數如何知道哪一個是正確的?你能用簡單的語言來解釋嗎?我是個新手,對此很感興趣。 – 2013-03-19 11:37:29