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

javascript - help me understand this structure (lexical scoping)

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

我们在这个 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
    }

}();  

第一行检查对象是否存在,如果不存在则使用shorthand定义{}创建一个Object。 ||比较。如果参数一为空,则设置参数二。

下一行的 if 检查对象上是否未设置 属性 myProject。 ! 是运算符。如果 myCompany.myProject returns 未定义此 if 子句 returns 为真。当为 true 时,将对象创建为 属性 myProject.

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

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

一次一张...

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 的提升。

希望这对您有所帮助,或者至少指出了一些您可以研究的内容,以找出您不完全理解的部分。

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

如果您试图帮助防止您的全局范围受到污染,那么您可能想要使用对象和类似于您正在做的事情。根据您想要的疯狂程度,您可以查看 Prototypical Inheritance.

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

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 = 立即调用的函数,而 returns 一个包含您想要封装的任何内容的对象。

你说的是这个吗?