在其他地方定义的 JavaScript 闭包

Javascript closure defined elsewhere

本文关键字:JavaScript 闭包 定义 其他 方定义      更新时间:2023-09-26

这是闭包的一个简单用法:

function Thing() {
    var _x;
    return {
        setX: function(val) { _x = val; },
        getX: function() { return _x }
    };
}
var a = Thing();
var b = Thing();
a.setX(12);
b.setX(23);
a.getX(); //returns 12

我想做的是能够定义setX的实现,并在Thing的定义之外定义getX

我尝试了这样的事情:

function setXimpl(val) {
    _x = val;
}
function getXimpl() {
    return _x;
}
function Thing() {
    var _x;
    return {
        setX: setXimpl,
        getX: getXimpl
    };
}
var a = Thing();
var b = Thing();
a.setX(12);
b.setX(23);
a.getX(); //returns 23 not 12!

很明显,setXimplgetXimpl正在设置/读取一些全局范围的_x,而不是在闭包内部。

我尝试了一堆其他的东西(主要是语法更改),但我就是无法让外部函数成为Thing闭包的一部分。有什么方法可以实现我想要的吗?

对你的问题的简短回答是否定的。

闭包的工作原理是访问函数作用域内的变量,这些变量在全局作用域中无法访问。仅当执行获取/设置的函数是已返回(创建闭包)的函数中的嵌套函数时,才会发生这种情况。这意味着Thing每次调用 setX 和 getX 时都必须创建 setX 和 getX 的新函数,就像在Thing代码中一样。

这并不意味着从 Thing 返回的函数不能通过使用(例如)IIFE 调用更接近全局范围的静态函数。定义事物:

var Thing = function(){
  function a(...) {...}; // create once
  function b(...) {...}; // create once
  return function () {   // the Thing function (create once)
      var _x;
      return {
          setX: function(val) { _x = val; },
          getX: function()    { return _x }
      };
     };
 }();

有效地为匿名 getter 和 setter 函数提供对静态定义的封装函数帮助程序的访问权限。

尝试工厂:

function setXimplLoader(x) {
  return function setXimpl(val) {
    x.value = val;
  };
}
function Thing() {
  var _x = { value: '' };
  return {
    setX: setXimplLoader(_x),
    getX: function() { return _x.value; }
  };
}
var a = Thing();
var b = Thing();
a.setX(12);
b.setX(23);
console.log(a.getX())

或者使用一些实用程序库:https://lodash.com/docs#partial