开发者

Check whether function result value is used

I was wondering whether it is possible to check whether a function is开发者_如何转开发 called in such a way that its return value is stored in a variable, or that it is called 'standalone'.

In the first case, the function should indeed return something, but otherwise it should save the value(s) to the current instance of my object.

To be specific, I have a Vector3D as follows:

function Vector3D(x, y, z) {
  this.x = parseNumber(x);
  this.y = parseNumber(y);
  this.z = parseNumber(z);
}

Vector3D.prototype.add = function(that) {
  return new Vector3D(
    this.x + that.x,
    this.y + that.y,
    this.z + that.z
  );
};

As can be seen, the add function returns something based on the object instance itself and on another instance. As it is now, the function must be called in a way like this:

var addedVector = vect1.add(vect2);

However, if I were to call it like this:

vect1.add(vect2);

it should not return anything (that's quite useless), but instead store the return coordinates (x, y and z) in the variables of vect1. So vect1 should become what is called addedVector in the other line of code.

To accomplish this, I guess I'm going to need to know whether the function is called alone or that its return value is stored.

Is there any way to accomplish this?


You could pretty easily break this apart into two functions, add(vector) and add_m(vector).

The second function (add_m) would mutate vector 1 and add the values of vector 2 to it and return nothing, whereas the first would make a new vector that is the result and return it.


I'm reasonably sure what you're describing is impossible. Even if it were, though, You'd probably not want to do it that way. Compare your code with a small variation:

var addedVector = vect1.add(vect2);
vect1.add(vect2);

var addedVector = eval("vect1.add(vect2)");
eval("vect1.add(vect2)");

I'm pretty sure that you'd like the lines with the evals to work the same as the ones without, right? Yet eval() trivially has to "use" the return value so it can propagate it outside.

Now, what I'd do is write any of the following functions that I happened to need:

v1.add(v2); // returns (v1+v2), v1 and v2 are unchanged
v1.addFrom(v2) // v1 = v1 + v2, v2 is unchanged, returns undefined
v1.addTo(v2) // v2 = v1 + v2, v1 is unchanged, returns undefined

depending on the usage, I might or might not have addTo/addFrom return the result.


There's no way to know how your caller has called your method, i.e. whether your caller has assigned the return value to a variable or not.


Nope. No way to do that, the function body is completely independent from the code context it's called in. Sounds like you want two separate functions, one to add in place and one to add and return a new value.


You cannot find that out. How about letting the function accept two parameters?

If only one is passed, you add it to the vector the function is called on.

If two are passed, you create a new one and sum them.

Something like:

Vector3D.prototype.add = function(vec1, vec2) {
    var target = vec2 ? new Vector3D(0,0,0) : this;
    vec1 = vec2 ? vec1 : this;
    vec2 = vec2 || vec1;

    target.x = vec1.x + vec2.x;
    target.y = vec1.y + vec2.y;
    target.z = vec1.z + vec2.z;

    return target;
}

Then you can call it with:

v1.add(v2); // adds v2 to v1

or

var addedVector = v1.add(v1, v2); // creates a new vector v1 + v2

But I agree that it is probably better to create two separate functions. A function should only do one thing.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜