【问题标题】:anobject.prototype v.s. Object.create(anobject.prototype) assignment [duplicate]anobject.prototype vs. Object.create(anobject.prototype) 赋值
【发布时间】:2020-12-20 20:58:27
【问题描述】:

以下代码与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);

【问题讨论】:

  • 快速投票否决?请说明原因。谢谢。

标签: javascript


【解决方案1】:

是的,存在显着差异。

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

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

这会将Student.prototype 属性的值替换为使用Person.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 对象的原型对象。在my answer here 中有更多详细信息,但从根本上说,要在 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-level 属性 (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);

【讨论】:

  • @snr - 我的荣幸!希望这会有所帮助(这本书也有帮助!)。
猜你喜欢
  • 1970-01-01
  • 2020-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
相关资源
最近更新 更多