$ .each()里面发生了什么?

时间:2014-02-09 17:27:25

标签: javascript jquery oop twitter-bootstrap

我遇到了一个我以前见过的问题,但我之前无法解决。我将来可能会再次发现它,所以请有人向我解释发生了什么事?

在下面javascript的部分片段中,我有一个填充屏幕的功能,包括一个订单组合框(twitter bootstrap)。当我点击该组合框中的一个订单商品时,它应该调用clsModCampaigns.blnCompaniesListReload()函数。

由于我不理解的原因,一旦进入'$ .each'迭代器,全局对象引用'objModCampaigns'就丢失了?我得到一个成功的警报'1',但没有警报'2'。

在$ .each中,我想使用'objModCampaigns.arrOrderBy'而不是'this.arrOrderBy',但$ .each迭代器似乎只是这样工作。为什么这样工作?

“this”发生了什么,或者使用'this'在类的根目录中分配变量/对象?

$ .each只是特别吗?

function clsModCampaigns(objSetSystem, objSetModuleBase)
{
  objModCampaigns = this;
  arrOrderBy = {
    intID: 'ID',
    strName: 'Name'};

  [...]

  this.blnScreenCampaignInitialize = function (fncSuccess,fncError, intID) {
    $.each(this.arrOrderBy, function (strFieldName, strFieldDescription) {
      if(strFieldName != 'datDeleted' || objSystem.blnHasPerm("CAMPAIGNS_DELETED")) {
        strOrderByID = "ulCampaignsCompaniesListOrderBy" + strFieldName;
        $("#ulCampaignsCompaniesListOrderBy").append('<li><a href="#" id="'+strOrderByID+'">'+strFieldDescription+'</a></li>');
        $("#"+strOrderByID).unbind("click").bind("click", function() {

          alert("1");
          objModCampaigns.arrCurrentShownCompanies.strOrderBy = strFieldName;
          objModCampaigns.blnCompaniesListReload();
          alert("2");

        });
      }
    });
    return true;
  };
}

2 个答案:

答案 0 :(得分:0)

您拥有的代码是

$.each(this.arrOrderBy, ...);

你想要

$.each(arrOrderBy, ...);

原因是该行的this上下文不同,因为它位于新函数this.blnScreenCampaignInitialize内。

这只是JavaScript工作方式的一部分

var message = "hello";

function welcome() {
  console.log(message);
}

welcome(); // "hello"

P.S。使用var

如果您不使用var,则会将所有变量附加​​到全局对象。

function hello() {
  foo = "bar";
  console.log(foo);
};

hello();          // "bar"
console.log(foo); // "bar"
// Holy smokes! `foo` has escaped our `hello` function!

将其与

进行比较
function hello() {
  var foo = "bar";
  console.log(foo);
}

hello();          // "bar"
console.log(foo); // ReferenceError: foo is not defined
// much better

现在让我们看一个可怕的例子

function a() {
  b = 5;
  return b;
}

function b() {
  return "function";
}

console.log(a()); // 5
console.log(b()); // TypeError: number is not a function

这种情况正在发生,因为我们没有正确使用var。我们首先将b定义为函数,但在运行a()后,b现在设置为5。第二个日志语句相当于尝试运行5(),因为b不再是函数。


PPS 使用strintfncobjcls为您的vars添加前缀非常不合常规的JavaScript。

根据你的评论,我理解你是一个“VB人”,但这并不是将你自己的约定带入语言的借口。我在你的个人资料中看到你精通荷兰语,英语,德语和法语。我建议你将学习编程语言与口语语言大致相同:每种语言都有自己明确的规则和约定。

这里有一堆free JavaScript books给你。我希望他们可以帮助你学习更多基础知识。


P.P.P.S。总体而言,您的功能非常大,我可以看到您已经使用[...]截断了部分代码。整个事情可能会从一些更好的组合中受益。

如果您粘贴所有代码,也许有人可以帮助您更好。

答案 1 :(得分:0)

What is going on inside the $.each() ?

关于你的问题标题,我想回答:

// each function in source
function (obj, callback, args) {
    //...
}

自己检查完整$.each function的来源,只需在相应的文本框中键入函数名称(第二个在顶部),即可看到任何函数的源代码。

each函数中,传入each函数(第一个参数)的数组/对象正在循环运行,每个值都传递给{{1} (第二个参数)并且回调正在执行,如:

callback

因此,每次循环发生时都会执行每个函数中传递的callback.apply(obj[i], args); ,并且循环中的当前值作为callback函数的参数与第三个参数{{一起传递1}}。

如果函数callback是正常函数,则此函数内的args指向全局function clsModCampaigns(){ //... }对象。所以只需使用:

this

而不是

window

因为$.each(arrOrderBy, ...); 在直接范围内,所以$.each(this.arrOrderBy, ...); 可以直接访问。例如:

arrOrderBy

关键字arrOrderBy的行为取决于上下文。查看function someThing() { var x = 'y'; //<-- this scope (everything inside someThing) is // global for somethingElse inner function function someThingElse)(x) //<-- possible to use directly { } } 上的this