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



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

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

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

代码如下:

'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.

这是小提琴:http://jsfiddle.net/6w2L1y5w/1/

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

事实上,这就是"特权访问器"在Javascript中的实现方式:你有一个"私有"变量和一个"公共"函数,它可以通过它定义的范围访问该变量。

(我在这里使用了很多"引号"围绕"私有"和"公共",因为这些是传统的OOP可见性概念,只是模糊地转移到Javascript。Javascript有简单的词法变量范围,句点。"隐私"等只是在某些模式中应用此范围机制来模拟基于类的 OOP 语义。

最新更新