美元.每个都在模块闭包中更改此上下文

$.each changes this context inside a module closure

本文关键字:上下文 闭包 模块 美元      更新时间:2023-09-26

我已经建立了一个标准的javascript模块(模式),其中包含了一些私有方法和变量。我发现我正在与使用$.each后维护this上下文指向我的模块进行斗争。

我知道,jQuery $.each方法创建一个闭包,因此一个新的"上下文",但我想继续有this指的模块。我发现调用我的模块的私有函数(示例中的initFruit())使用initfruit_call()并传入thisself副本(这是"在范围内")为该函数工作,但是一旦该函数调用另一个函数,上下文再次丢失。

我真的不想一直用。call()调用我所有的私有函数,因为我使用了$.each进一步向上调用堆栈,所以我如何使用$.each而不丢失我的原始上下文?

小提琴:https://jsfiddle.net/BloodBaz/zz11n5wp/1/

在作用域上下文中,您定义了替代this的内部闭包(例如:90%的情况是在私有"方法"中),拥有"全局作用域"的this元素的最简单方法是定义一个变量,通常是在主代码块的第一行中定义self。在您的情况下,"全局"thisWindow,因此这就是我要做的,简单地说,当您想引用对象和this时,仅当您想引用内部闭包时,将"this"替换为"self":

var MyModule = (function ($) {
    var self = {};
    var privateFunction = function () {
        console.log(self);
    }
    self.init = function () {
        privateFunction(); // exposes all the public methods of self, keeping the "private" functions private
    };
    return self;
}(jQuery));
MyModule.init();
https://jsfiddle.net/zz11n5wp/2/

您可以尝试将函数绑定到您想要的作用域吗?有点像下面

var self = this;    
$.each([1,2,3,4], function(index, item) {
  // do something
  // self === this
}.bind(this));

或者如果你需要旧的浏览器支持,可以尝试使用lodash之类的库来实现。或者jquery的$。代理应该可以工作。

https://jsfiddle.net/zz11n5wp/3/