我正在通过一些JavaScript语言来学习语言语法,这组测试让我感到困惑:

it("should know that variables inside a constructor and constructor args are private", function () {
    function Person(firstname, lastname)
    {
      var fullName = firstname + " " + lastname;

      this.getFirstName = function () { return firstname; };
      this.getLastName = function () { return lastname; };
      this.getFullName = function () { return fullName; };
    }
    var aPerson = new Person ("John", "Smith");

    aPerson.firstname = "Penny";
    aPerson.lastname = "Andrews";
    aPerson.fullName = "Penny Andrews";

    expect(aPerson.getFirstName()).toBe("John");
    expect(aPerson.getLastName()).toBe("Smith");
    expect(aPerson.getFullName()).toBe("John Smith");

    aPerson.getFullName = function () {
      return aPerson.lastname + ", " + aPerson.firstname;
    };

    expect(aPerson.getFullName()).toBe("Andrews, Penny");
  });


我知道构造函数中的变量是私有的,这就是为什么即使尝试设置aPerson.firstname,lastname和fullName,在调用getFullName()时仍然显示“ John Smith”的原因。但是随后创建了一个名为getFullName()的函数,然后调用该函数打印“ Andrews,Penny”。

我本来希望打印“ Smith,John”,因为在“失败”尝试将名字设置为“ Penny”和姓氏设置为“ Andrews”之后创建了此新功能。为什么打印“ Andrews,Penny”?

谢谢

最佳答案

这里的关键是new operator; var aPerson = new Person ("John", "Smith")创建一个新的Person,传入JohnSmith作为Person函数使用的名称,并将该函数的新实例分配给变量aPerson

注意var fullName = firstname + " " + lastname函数内部的Person。这将在调用Person函数时将传递给函数的参数作为函数参数。此时,this.getFullName将等于John Smith

当您运行aPerson.firstname = "Penny"
这只会更新Person的新实例;它不会修改原始的Person函数。当您调用aPerson.getFirstName()时,getFirstName()方法将返回最初为firstname(John)设置为Person的内容,而不是为新实例aPerson(Penny)设置的内容。

因此,第一次调用aPerson.getFullName()时,名称为John Smith

您的新函数aPerson.getFullName = function () { }返回aPerson.lastname + ", " + aPerson.firstname。与以前的函数不同,它从Person的新实例(Penny Andrews)中获取姓氏和名字。

这样,第二次调用aPerson.getFullName()时,名称为Penny Andrews

希望这可以帮助! :)

09-18 23:53