为什么允许通过原型继承访问另一个闭包范围内的私有变量?

Why does accessing a private variable in another closure's scope via prototypical inheritance allowed?

所以我能够通过原型继承意外访问私有变量 (numb)。我有几个问题:

  1. 自调用匿名函数(SIAF)闭包中的这些私有变量不应该在SIAF执行完后就已经过期了吗?我原以为它会因为 'use strict'.

  2. 而出错
  3. 如果变量永不过期,作为最佳实践的一部分是否应该避免这种情况?

代码如下:

'use strict';

var GLOBAL = {};


// SELF-INVOKING ANONYMOUS FUNCTION
(function(){

    var numb = 110;
    var Person = function(first_name, last_name) {
        this.name = first_name + ' ' + last_name;
    };

    Person.prototype.getNumb = function() { return numb; };

    GLOBAL.Person = Person;
})();


// ANOTHER SELF-INVOKING ANONYMOUS FUNCTION
(function(){
    function Animal(type_of_animal) {
      this.type = type_of_animal; 
    }

    Animal.prototype = Object.create(GLOBAL.Person.prototype);
    GLOBAL.Animal = Animal;
})();



var dog = new GLOBAL.Animal('dog'); 
console.log( dog.getNumb() ); // This logs 110 to the console.

这是 fiddle:http://jsfiddle.net/6w2L1y5w/1/

Javascript 中的变量作用域是词法的。这意味着,范围与源代码中所写的完全相同。函数 getNumb 定义在与变量 numb 相同的词法范围内,它的主体引用该变量 (return numb)。您如何或从何处调用该函数并不重要。这就是闭包的工作方式。

事实上,这就是 "privileged accessors" 在 Javascript 中的实现方式:您有一个 "private" 变量和一个 "public" 函数,它可以通过它定义的范围。

(我在 "private" 和 "public" 周围使用了很多 "quotes",因为这些是传统的 OOP 可见性概念,只能模糊地转移到 Javascript.Javascript 具有简单的词法变量作用域,句点。"Privacy" 只是在某些模式中应用此作用域机制来模拟基于 class 的 OOP 语义。)