接受的答案肯定会奏效。这个“简短”的解释变成了漫谈,但希望它会有所帮助。
对于接受的答案,您必须注意一件事。当你通过这样做基本上“继承”时,Bar.prototype = new Foo()
你正在调用构造函数。因此,如果您的构造函数中有不希望用作另一个“类”的启动板的代码,那么您将得到奇怪的效果。举个例子:
var Person = function (firstName, lastName) {
....
};
var Student = function (firstName, lastName, grade) {
....
};
假设这Student
是Person
. 您将如何构建原型Student
?可能不喜欢Student.prototype = new Person("John", "Doe");
一种不同的处理方式,它有点复杂,但可以包装在另一个函数中,如下所示:
var extend = function (child, parent) {
var f = function () {};
f.prototype = parent.prototype;
child.prototype = new f();
child.prototype.constructor = parent;
}
var Person = function (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.getName = function () {
return this.firstName + " " + this.lastName;
}
Person.prototype.setAge = function (age) {
this.age = age;
}
var Student = function (firstName, lastName, grade) {
Person.call(this, firstName, lastName);
this.grade = grade;
};
extend(Student, Person); //<< do this before adding stuff to the prototype
Student.prototype.getName = function () {
var name = Person.prototype.getName.apply(this);
return name + ", Grade " + this.grade;
}
Student.prototype.tooOldToBeAStudent = function () {
if(this.age > 18) { return true; }
}
var p = new Person("Joe", "DiMaggio");
var s = new Student("Jack", "Sparrow", 12);
console.log(p.getName(), s.getName());
//consoles "Joe DiMaggio" "Jack Sparrow, Grade 12"
console.log(s instanceof Person);
//true - even with the weird looking inheritance, Student is still an instance of Person.
s.setAge(30);
console.log(s.age);
//30, just like what you'd expect with a Person object.
console.log(s.tooOldToBeAStudent);
//true - as mentioned previously, 'age' is set via its inherited method.
这不仅为您提供了 Person 功能,还允许您在此基础上进行构建。有点像你实际上对继承所做的事情。
它是如何工作的?好问题。首先,对象是通过引用[基本上]分配的。原型是一个对象。因此,在extend
函数中,我创建了一个空白函数,作为child
. 这会将parent
' 的原型复制到自身,然后将自身的新实例作为 的原型child
。这样parent
不会调用 ' 的构造函数,但仍使用父级的原型。为了确保它instanceof
仍然有效,child.prototype.constructor
设置为parent
- 有效地通知 javascript 孩子来自父母,而不是代理人。
此外,当覆盖方法时,您可以使用您从原型方法继承的“类”和apply
/或call
它this
- 在当前对象的范围内运行该方法,并且您可以传递任何您认为的参数,但它们被接受您选择的功能。例如,在学生的当前实例的上下文中Person.prototype.getName.apply(this);
运行 Person's getName
。假设我们想要覆盖 setAge 以简单地 console.log 退出年龄。
Student.prototype.setAge = function () {
Person.prototype.setAge.apply(this, arguments);
console.log(this.age);
}
这里发生的是使用传递给 ' Person
ssetAge
的参数调用Student
's setAge
。因此,它基本上允许这些东西通过,而您不必知道原始方法参数的细节。