aPerson.firstname和aPerson.lastname何时在此代码段中实际更改?

时间:2017-12-11 22:48:56

标签: javascript syntax

我正在浏览一些JavaScript koans来学习语言语法,我对这组测试感到困惑:

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");
  });

我得到构造函数中的变量是私有的,这就是为什么“John Smith”在调用getFullName()时仍会打印,即使在尝试设置aPerson.firstname,lastname和fullName之后也是如此。但是后来创建了一个名为getFullName()的函数,然后调用函数“Andrews,Penny”打印。

我本来期望“史密斯,约翰”打印,因为这个新功能是在“失败”尝试将名字设置为“Penny”并将姓氏设置为“安德鲁斯”之后创建的。为什么“安德鲁斯,便士”打印?

由于

2 个答案:

答案 0 :(得分:1)

这里的关键是 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 (约翰)最初设置为Person的内容,而不是已为新实例aPerson(Penny)。

因此,当您第一次拨打aPerson.getFullName()时,名称为John Smith

您的新功能aPerson.getFullName = function () { }会返回aPerson.lastname + ", " + aPerson.firstname。与上一个函数不同,它使用Person(Penny Andrews)的 new 实例中的姓氏和名字。

因此,第二次拨打aPerson.getFullName()时,名称为Penny Andrews

希望这有帮助! :)

答案 1 :(得分:0)

首先,您需要了解这一点:

function Person(firstname, lastname)
{
  var fullName = firstname + " " + lastname;
  ...
}

var aPerson = new Person ("John", "Smith");

在这里,你创建的唯一东西是一个只有方法的对象,甚至不是属性,比如firstname,lastname。 (用var声明的参数和变量没有附加到您的对象)

所以你的对象aPerson是这样的:

{
    getFirstName: function(), // => John
    getLastName: function(), // => Smith
    getFullName: function() // => John Smith
}

然后:

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

您在aPerson对象上分配了新属性。所以,它变成了这样:

{
    firstname: "Penny",
    lastname: "Andrews",
    fullName: "Penny Andrews",
    getFirstName: function(), // => John
    getLastName: function(), // => Smith
    getFullName: function() // => John Smith
}

接下来,用这个覆盖getFullName:

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

如您所见,您使用这些新属性。

现在,您应该能够理解您的结果。 如果你做了替换,你会得到这个:

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

瞧!这就是你获得结果的原因;)