javascript - 帮助我理解这个结构(词法范围)

时间:2015-01-08 01:28:06

标签: javascript function

以下是我试图理解的一些代码的简化。

我们在这个javascript片段中尝试做什么?我们似乎正在创建名为myCompany的对象(?)(如果尚未创建),然后将子对象myProject添加到myCompany。 然后在myCompany.myProject中创建局部变量,在函数myCompany.myProject.myfunction中创建另一个局部变量。最后的()使其立即执行。我们这样做是为了让localVariable_1远离全球空间吗?

var myCompany= myCompany || {};   
if (!myCompany.myProject) {
    myCompany.myProject = {};
}

myCompany.myProject = function () {

    var localVariable_1;

    function myFunction(){
        var anotherlocalVariable;
        // .. do some stuff
    }

}();  

3 个答案:

答案 0 :(得分:2)

第一行检查对象是否存在,如果不使用速记定义{}来创建对象。 ||比较。如果参数one为null,则设置参数二。

下一行的if检查是否未在对象上设置属性myProject。 !是运营商。如果myCompany.myProject返回undefined,则此if子句返回true。当true创建对象作为属性myProject。

第三部分:myProject被一个函数对象取代。此函数在{和}之间定义,但由函数声明后面的()立即调用。

localvariable_1永远不会在全局范围内,因为它具有var语句。将它绑定到myCompany.myProject函数的范围。也许直接调用此函数来设置一些初始值,但将它们包装在一个可以重用的函数中,以便在另一个时刻更改值。

答案 1 :(得分:1)

一次一件......

var myCompany= myCompany || {};

如果存在myCompany,则将其设置为它,否则创建一个空对象并将myCompany设置为空对象。

注意:如果myCompany已经存在,则您没有指示它是什么

if (!myCompany.myProject) {
    myCompany.myProject = {};
}

现在你知道myCompany是一个对象,你验证它有一个project属性。如果不是,则将myProject设置为空对象。

注意:您没有对myProject进行过任何测试,所以再次没有指示它是什么

myCompany.myProject = function () {
  var localVariable_1;
  function myFunction(){
    var anotherlocalVariable;
    // .. do some stuff
  }
}();

您在这里分配myCompany.myProject。请注意()之前的;,这使得此函数立即执行。在函数内部,您正在创建另一个当前没有执行任何操作的函数。如果您没有从函数返回,我认为它会将myProject设置为undefined。

您可能已经知道什么是立即函数,但如果不是,它基本上是一个立即被调用的函数。将它包装在()中也是标准的,以便更容易阅读,例如

var someFunction = (function () { 
    /*whatever*/
} ());

你说这是从原版中简化的所以我猜你删除了实际做事的代码的一个重要部分,但混淆可能是由于JavaScript的范围界定方式。它使用了所谓的词法范围。您可以将其视为功能范围。

另一件可能让你失望的事情是JavaScript如何使用 truthy 评估来进行逻辑比较。

最后一件事可能是混淆了你阅读代码的方式是javascript的提升。

希望这有助于或至少指出一些你可以研究的事情来找出你并不完全理解的部分。

答案 2 :(得分:1)

抱歉,我只是讨厌写评论lol。

如果您正在尝试帮助防止全局范围受到污染,那么您可能希望使用对象和类似于您正在执行的操作。根据您想要获得的疯狂程度,您可以查看原型继承

常见的模式是做这样的事情

var company = (function() {
  var name;

  var getName = function() { 
    return name;
  };

  var setName = function(n) { 
    name = n;
  };

  return {
    getName : getName,
    setName : setName
  }
}())

现在你可以做company.setName("yoda")或其他任何事情。

这将为您提供一个基本的getter和setter,其中没有人可以在不通过getter和setter的情况下更改公司名称,并且它也不会污染全局范围。您可以通过这种方式获得公司所需的任何内容,并将数据封装在对象中。

注意var company =如何立即调用一个返回一个对象的函数,该对象包含你想要封装的对象。

这就是你在说什么?