简体   繁体   中英

How to not pass arguements and still make the function work?

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();
}

And then I want to call the function like this:

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

As you can see I have skipped the lWidth parameter. I want the function to still work, even when the lWidth is not passed as a parameter. How will I do this? Atm, it might think that the someCapStyle is the lwidth .

When you have a big amount of arguments to pass into a function like you have, use an object:

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

In that case you wont be depend on number of arguments and order of them being represented.

So you can rewrite your function:

 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();
}

When you don't pass any argument, undefined value is passed instead, so just check in the function whether the argument has been passed or not:

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

So to not pass lWidth , just pass undefined as its value

PS the best way is to use a single argument args , which will be object containing all current parameters as properties.

What you want is to partially evaluate the drawLine function, assigning a constant value to lWidth . There's a JavaScript library called Jeene that does just this. This is how you would use it:

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
});

Then you use drawLine2 as follows:

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

This is called specialization and is a very useful pattern. Read more about it: A Neighborhood of Infinity: The Three Projections of Doctor Futamura

You can put the optional parameter at the end of the paramter list. That way, if you leave it out, the other parameters won't be affected.

Another option would be to pass a single object with the attributes you want to define eg

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

You can not use "function overloading" in Javascript, but here is a way to achieve what you want:

How to overload functions in javascript?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM