在构造函数中定义的私有变量的ES5难题

时间:2017-08-26 09:42:00

标签: javascript closures ecmascript-5

我正在阅读“适用于网络开发者第3版的专业JavaScript”中的私有变量部分,并对其中一个示例代码感到困惑:

function Person(name) {
  this.setName = function(value) {
    name = value;
  }

  this.getName = function() {
    return name;
  }
}

var person1 = new Person('p1');
person1.setName('p11');
person1.getName();  // 'p11'

var person2 = new Person('p2');
person2.getName();  // 'p2'

getName()方法通过闭包和作用域链访问name变量,而setName()方法为name分配新值。

问题:

name变量在哪里?

为什么Person的每个实例都有不同的name,因此如果一个实例修改name变量,它不会影响其他实例?

====================================

我认为每次使用new创建实例时,都会创建Person Activation Object。每个name中的Person Activation Object变量都不同。

1 个答案:

答案 0 :(得分:1)

此行为与new无关。

每次调用Person时,都会创建一个新的独立的参数变量name实例。该函数内的代码可以访问该变量。没有更多的东西。

对于您可能声明的每个函数中的参数变量都是如此。只要可以引用这些变量,它们就会保留在内存中 - 它们不会被垃圾收集。

调用Person两次,实质上与调用两个具有相同参数和方法的不同函数没有太大区别:

function Person1(name) {
  this.setName = function(value) {
    name = value;
  }

  this.getName = function() {
    return name;
  }
}

function Person2(name) {
  this.setName = function(value) {
    name = value;
  }

  this.getName = function() {
    return name;
  }
}

var person1 = new Person1('p1');
person1.setName('p11');
person1.getName();  // 'p11'

var person2 = new Person2('p2');
person2.getName();  // 'p2'

当然,这里person1person2不再是同一个构造函数的实例,但除此之外,单独的变量实例和范围的原理是相同的。