Javascript 原型属性阴影

Javascript prototype property shadowed

本文关键字:阴影 属性 原型 Javascript      更新时间:2023-09-26

我对Javascript原型机制有点困惑。我有以下代码:

function Person () {
  this.name = "no name";
  this.setName = function (n) {
    this.name = n;
  }
}
function Student () {
  this.id = "123";
}
Student.prototype = new Person();
s = new Student();
s.setName("Klaus");

执行代码后,对象 s 有两个名称。对象本身的名称"Klaus"和原型中的"noname"名称。我知道这个物业是阴影的,它工作得很好,但这感觉不自然?!有没有更好的方法只使用原型的属性?

您可以直接处理原型属性,但这需要不成比例的工作量,并且可能不被视为最佳实践。相反,您可以在正确的this上下文中调用 Person 构造函数。

首先,强烈建议在分配给函数的 prototype 属性时使用 Object.create 而不是 new 运算符。使用 new 运算符时,将调用 Person 构造函数,但在错误的this上下文中。为了防止这种情况,您可以像这样链接它们:

Student.prototype = Object.create(Person.prototype);

相反,如果要在 Student 中调用原型链接 ( Person) 的构造函数,则可以在构造函数中使用正确的this上下文call它:

function Student () {
  Person.call(this);
  this.id = "123";
}

另外,除非您想为每个实例创建一个函数,否则我会将setName函数移动到Person[[Prototype]]

function Person () {
  this.name = "no name";
}
Person.prototype.setName = function (n) {
  this.name = n;
}
function Student () {
  Person.call(this); // Call the Person constructor
  this.id = "123";
}
Student.prototype = Object.create(Person.prototype);
s = new Student();
// s.name is 'no name'
s.setName("Klaus");
// s.name is 'Klaus'

或者,如@Teemu所述,您也可以将 name 属性放在Person.prototype上以将其用作默认值:

function Person () {
}
Person.prototype.setName = function (n) {
  this.name = n;
}
Person.prototype.name = "no name"; // Define the name directly
function Student () {
  Person.call(this); // you only need this, if there are other things happening in the Person constructor that you need as well
  this.id = "123";
}
Student.prototype = Object.create(Person.prototype);
s = new Student();
// s.name is 'no name'
s.setName("Klaus");
// s.name is 'Klaus'