JavaScript: automatic getters and setters in closures without eval?

烂漫一生 提交于 2019-12-10 22:19:10

问题


Note: there are a lot of questions regarding getters and setters in JavaScript (see Javascript Getters And Setters, Getters and Setters in a function (javascript), Getters and Setters in JavaScript (Correct syntax ?), automatic getter and setter(with validation) in javascript, etc). Most of these questions deal with Objects, a few with Closures and rather few of them with automatically producing getters and sets. This question deals with the later.

The answer to automatic getter and setter(with validation) in javascript is perhaps the closest for what I am looking for, but not-ideal for my use case.

Currently, in my closure I have the following:

function myClosure() {
  var closureVar1, closureVar2

  function do () { ... }

  function setupSettersAndGetters() {

    var closureVariables = ['closureVar1', 'closureVar2']

    for (var i = 0; i < closuredVariables.length; i++) {

      var currentClosureVariable = closureVariable[i]
      var toEvaluateString = "                                                 \
      do." + currentClosureVariable + " = function(value){                     \
        if(!arguments.length) return " + currentClosureVariable + ";           \
        " + currentClosureVariable + " = value;                                \
        return setup;                                                          \
      };                                                                       \
      "
      eval(toEvaluateString)
    }
  }
  setupSettersAndGetters()
  return do;
}

This works exactly as I like, e.g.

var test = myClosure()
test.closureVar1(10).closureVar2(2)
test.closureVar1() + test.closureVar2() // return 12

There is just the one "tiny" problem of using eval which some people detest.

So my question is, is there a better way to handle this and allow for me to call the setter / getter by name, rather than using a string?

e.g. I could use an intermediate function such as:

test.sget('closureVar1', 10) // set closureVar1 to 10
test.sget('closureVar2') // get closureVar2

but even doing that I think I still need to use eval? and I would prefer calling the name of the variable...

Thoughts?


回答1:


You can take the arguments passed to your myClosure function...

var args = Array.prototype.slice.call(arguments);

... and use them to set up your setters and getters:

args.forEach(function(arg) {
    instance[arg] = function(d) {
        if (!arguments.length) return arg;
        arg = d;
        return instance;
    };
});

That way, you can pass how many variables you want and also avoiding eval.

Here is a demo:

function myClosure() {
  var instance = {};
  var args = Array.prototype.slice.call(arguments);
  args.forEach(function(arg) {
    instance[arg] = function(d) {
      if (!arguments.length) return arg;
      arg = d;
      return instance;
    };
  })
  return instance;
};

var test = myClosure("v1", "v2", "v3")
test.v1(16).v2(2).v3(8)
console.log(test.v1() + test.v2() + test.v3())


来源:https://stackoverflow.com/questions/49473700/javascript-automatic-getters-and-setters-in-closures-without-eval

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!