我正在通过一些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
,传入John
和Smith
作为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
。
希望这可以帮助! :)