JS - Accessing Function Parameters Array Outside o

2019-07-31 12:11发布

问题:

BRIEF: I have frequented SO for years, but this is my first post. I've heavily searched SO for this, so I'm sorry if I overlooked it and this is a duplicate.

function actionFunction(values) {
    this.defaultValues = {
        valueX : 2.5,
        valueY : 5.5
    };
    this.valuesRanges = {
        xRange : { min : 0, max : 10 },
        yRange : { min : 5, max : 10 }
    };
 };

Obviously I can access these within the function itself using this.defaultValues.valueX, etc. What I'd like to know is how to access these outside of the function? I'm aware this is most likely a return or scope/hoisting problem and just do not know how to attack it.

Essentially, I need to get actionFunction.defaultValues.valueX. Also, I'd like to get the values inside of actionFunction.valuesRanges.xRange. I've tried these as arrays and more, but just can't figure out the correct, proper methodology. I have a multitude of functions structured like this that I need to pull these values from, so a modular way to do so without bringing in jQuery just for $.extend() and other basal functionality at the cost of overhead would be great.


EDIT I realized after posting this that I forgot to mention I was properly calling var example = new actionFunction();, but for some reason am/was having issues.

That said, what would be a cleaner and more logical, reliable way to store these values within the function as opposed to the this method so that they could still be grabbed by an exterior call for the values like previously mentioned?

回答1:

It seems you're misunderstanding how exactly you should go about using functions that use this. Generally, we use these sorts of functions to construct objects based on them -- we call these functions "constructors". To use a constructor, you have to use the new keyword, passing any necessary arguments. For example, if we had this constructor:

function Test() { this.a = 1; }

We could create an instance (an object based on a constructor) by doing:

var foo = new Test();
console.log(foo.a); // 1

However, calling it as a normal function will not work as intended, as @Tibos pointed out -- that's probably not what you wanted. In most circumstances, it'll be defined in the global scope (that's where variables go by default). However, you shouldn't call a constructor like a normal function, as the value of this can change in some situations and the misuse of this in your function is likely to mislead others.

var foo = Test(); // no "new"
console.log(a); // 1
console.log(foo.a); // TypeError: Cannot read property 'a' of undefined

Let's go back to your original constructor. By using new with your constructor, instead of calling it as a normal function, we can do this:

function actionFunction(values) {
    this.defaultValues = {
        valueX : 2.5,
        valueY : 5.5
    };
    this.valuesRanges = {
        xRange : { min : 0, max : 10 },
        yRange : { min : 5, max : 10 }
    };
}

var example = new ActionFunction();
console.log(example.defaultValues.valueX); // 2.5

If you'd like, you can make sure that it always returns an instance by doing a check:

if (!(this instanceof actionFunction)) return new ActionFunction(arg1, arg2, ...);

It's usually simpler though to always remember to use new for constructors than to include this though -- most people don't bother including this check in their code.



回答2:

this is the object your function was called on. this.defaultValues is a property of that object. If your function wasn't called on anything, then the global (window) object will be this, thus this.defaultValues will be window.defaultValues, which is also accessible as defaultValues

function actionFunction(values) {
    this.defaultValues = {
        valueX : 2.5,
        valueY : 5.5
    };
    this.valuesRanges = {
        xRange : { min : 0, max : 10 },
        yRange : { min : 5, max : 10 }
    };
 };

actionFunction();

console.log(window.defaultValues); // Object {valueX: 2.5, valueY: 5.5} 
console.log(defaultValues); // Object {valueX: 2.5, valueY: 5.5} 

If you call the function on an object, then this will be that object and this.defaultValues will be obj.defaultValues.

var obj = {};
actionFunction.call(obj);

console.log(obj.defaultValues); // Object {valueX: 2.5, valueY: 5.5} 

A similar thing happens when you use the function as a constructor, except that the object will be created implicitly and returned by the constructor:

var o = new actionFunction();

console.log(o.defaultValues); // Object {valueX: 2.5, valueY: 5.5} 


回答3:

Your "function" is here obviously a JS class definition.

To access it, you'll need to create an "instance" of this class through new;

Sample:

var af=new actionFunction();
var defaultX=af.defaultValues.valueX;
var vrangeymin=af.valuesRanges.yRange.min;


回答4:

defaultValues and valuesRanges are set as properties on whatever this refers to when the function is invoked. Presumably you're treating that function as a constructor and invoking it with the new operator, which would mean this refers to a new instance:

var instance = new actionFunction();
instance.defaultValues; // This will be a reference to the object in question

If that's not what you're doing, you probably don't want to use this, as it will refer to the global object.

If that's the case, and you need to access that object outside of the function, you could simply declare it outside the function where it will be accessible to any descendant scopes.

If you haven't done that because you have several "action functions" that should have their own set of default values you could set them as static properties on the function objects:

actionFunction.defaultValues = { /*...*/ };