anobject.prototype v.s. Object.create(anobject.prototype) as



以下代码与prototype赋值有什么不同吗。如果是,我可以学习吗?

function Person(name, lastname)
{}
Person.prototype.school = `GTU`
function Student(name, lastname) {
this.name = name
this.lastname = lastname
}
Student.prototype = Person.prototype                            //   <-----
Student.prototype = Object.create(Person.prototype)             //   <-----
Student.prototype = new Person()                                //   <-----
//Student.prototype.constructor = Student
const me = new Student(`a`, `b`)
console.log(me);

是的,存在显著差异。

这将用Person.prototype:的值替换Student.prototype属性的值

Student.prototype = Person.prototype                            //   <-----

这将用一个使用Person.prototype作为原型的新对象替换Student.prototype属性的值:

Student.prototype = Object.create(Person.prototype)             //   <-----

(如果在ES5及以下版本中通过构造函数进行继承链,这通常是您想要的。(

这使用Person.prototype作为原型创建了一个新对象,但也调用Person构造函数对其进行初始化:

Student.prototype = new Person()                                //   <-----

这通常不是您想要的,因为您不是在创建Person实例,而是在设置构造函数链。


顺便说一句,在你做了你通常想做的事情之后:

Student.prototype = Object.create(Person.prototype)             //   <-----

你还想这样做:

Object.defineProperty(Student.prototype, "constructor", {
value: Student,
writable: true,
configurable: true
});

否则,constructor属性将与其标准值(Person(一起继承,这不适用于将分配给Student对象的原型对象。在我的回答中有更多的细节,但从根本上讲,要在ES5中建立链,你应该这样做:

function Person(name, lastname) {
// Since you're accepting these as parameters, you probably want to store them
this.name = name;
this.lastname = lastname;
}
Person.prototype.school = `GTU`;
function Student(name, lastname, studentNumber) {
// Since `Student` derives from `Person`, let `Person` do its initialization
Person.call(this, name, lastname);
// Here we do `Student`-specific initialization
this.studentNumber = studentNumber;
}
// Set up `Student` as a subclass of `Person`
Student.prototype = Object.create(Person.prototype);
Object.defineProperty(Student.prototype, "constructor", {
value: Student,
writable: true,
configurable: true
});
// Example of using `Student`:
const me = new Student(`a`, `b`, 1234);
console.log(me);

我添加了一个Student级别的属性(studentNumber(来强调应该在哪里初始化每组属性。

在ES2015+中,如果要使用构造函数来设置继承链,基本上没有理由不使用class语法。(但只有当你使用构造函数来建立继承链时;JavaScript有其他可以使用的范式,你不必使用构造函数。(

class Person {
constructor(name, lastname) {
// Since you're accepting these as parameters, you probably want to store them
this.name = name;
this.lastname = lastname;
}
// Before too long, you'll be able to replace the assignment that's after the
// `class` with the following:
// static school = `GTU`;
}
Person.prototype.school = `GTU`;
class Student extends Person {
constructor(name, lastname, studentNumber) {
// Let `Person` do its initialization
super(name, lastname);
// Here we do `Student`-specific initialization
this.studentNumber = studentNumber;
}
}
// Example of using `Student`:
const me = new Student(`a`, `b`, 1234);
console.log(me);

最新更新