【问题标题】:Setting a variable in the closure scope在闭包范围内设置变量
【发布时间】:2013-03-31 23:38:28
【问题描述】:

我想我理解为什么变量存在于声明它们的函数之外,因为你正在返回另一个函数:

myFunction = function() {
    var closure = 'closure scope'
    return function() {
        return closure;
    }
}
A = myFunction(); // myFunction returns a function, not a value
B = A(); // A is a function, which when run, returns:
console.log(B); // 'closure scope'

现在的写法,调用 A() 就像一个 getter。

问:如何编写 myFunction 以使调用 A(123) 成为 setter?

【问题讨论】:

  • 说“不是价值”有点误导;一个函数一个值。

标签: javascript closures


【解决方案1】:

尝试以下方法:

myFunction = function() {
    var closure = 'closure scope'

    // value is optional
    return function(value) {
        // if it will be omitted
        if(arguments.length == 0) {
            // the method is a getter
            return closure;
        } else {
            // otherwise a setter
            closure = value;
            // with fluid interface ;)
            return this;
        }
    }
}
A = myFunction(); // myFunction returns a function, not a value
A(123); // set value
B = A(); // A is a function, which when run, returns:
console.log(B); // '123'

【讨论】:

  • 谢谢托尔斯滕!我没有考虑使用长度属性来确定是否有参数。这很好。
  • 使用它,您也可以将属性设置为nullfalse。很长一段时间我都没有真正编写过 js,但我记得 有些东西 :)
【解决方案2】:

例如,如果你想要 getter 和 setter,你可以这样做:

var func = function() {
  var closure = 'foo';

  return {
    get: function() { return closure; },
    set: function(value) { closure = value; }
  }
};

var A = func();

A.set('foobar');
console.log(A.get()); //=> "foobar"

【讨论】:

  • 感谢 elclanrs。我查看了 JavaScript 的 getter 和 setter,但我想我想使用 jQuery 样式的 getter 和 setter,其中调用不带参数的函数被认为是 getter,而使用参数调用它被认为是 setter。
【解决方案3】:

应该很简单:

myFunction = function() {
    var closure = 'closure scope'
    return function(setTo) {
        if (typeof setTo !== "undefined") {
            closure = setTo;
            return this; //support call chaining, good idea hek2mgl
        } else {
            return closure;
        }
    }
}

由于closure 变量在函数作用域的闭包内,您应该能够以与从中读取相同的方式对其进行赋值。

见 jsFiddle:http://jsfiddle.net/WF4VT/1/

【讨论】:

  • 如果setTo0 怎么办? ;)
【解决方案4】:

另一种选择是使用一个类并定义 getter 和 setter:

function MyClass(p){
    this._prop = p;
}
MyClass.prototype = {
    constructor: MyClass,
    get prop(){
        return this._prop;
    },
    set prop(p){
        this._prop = p;
    }
}

var myObject = new MyClass("TEST");
console.log(myObject.prop);
myObject.prop = "test";
console.log(myObject.prop);

演示:http://jsfiddle.net/louisbros/bMkbE/

【讨论】:

    【解决方案5】:

    jsFiddle Demo

    让你返回的函数接受一个参数。将其用作设置器:

    myFunction = function() {
     var closure = 'closure scope';
     return function(val) {
        closure = val;
        return closure;
     }
    }
    A = myFunction(); // myFunction returns a function, not a value
    B = A(123); // A is a function, which when run, returns:
    console.log(B); // 'closure scope'
    

    【讨论】:

      【解决方案6】:

      重新审视这个问题,我发现我可以这样做:

          function outside() {
          	var result = 'initialized'
          	return inside
          	function inside(argVariable) {
          		if(arguments.length) {
          			result = argVariable
          			return this
          		} else {
          			return result
          		}
          	}
          }
          myFunction = outside() // outside returns a function
          X = myFunction() // returns: 'initialized'
          $('body').append(X + '<br>')
          myFunction(123) // setter
          X = myFunction() // returns: 123
          $('body').append(X)
      &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-22
        • 2016-04-30
        • 1970-01-01
        • 2018-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多