typescript 访问基类成员

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13121431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 00:54:41  来源:igfitidea点击:

Accessing member of base class

typescript

提问by Jaap

See the inheritance example from the playground on the TypeScript site:

请参阅 TypeScript 站点上操场上的继承示例:

class Animal {
  public name;
  constructor(name) {
    this.name = name;
  }
  move(meters) {
    alert(this.name + " moved " + meters + "m.");
  }
}

class Snake extends Animal {
  constructor(name) {
    super(name);
  }
  move() {
    alert("Slithering...");
    super.move(5);
  }
}

class Horse extends Animal {
  constructor(name) {
    super(name);
  }
  move() {
    alert(super.name + " is Galloping...");
    super.move(45);
  }
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);

I have changed one line of code: the alert in Horse.move(). There I want to access super.name, but that returns just undefined. IntelliSense is suggesting that I can use it and TypeScript compiles fine, but it does not work.

我更改了一行代码:Horse.move(). 我想访问那里super.name,但它只返回undefined. IntelliSense 建议我可以使用它并且 TypeScript 编译得很好,但它不起作用。

Any ideas?

有任何想法吗?

回答by Fenton

Working example. Notes below.

工作示例。注释如下。

class Animal {
    constructor(public name) {
    }

    move(meters) {
        alert(this.name + " moved " + meters + "m.");
    }
}

class Snake extends Animal {
    move() {
        alert(this.name + " is Slithering...");
        super.move(5);
    }
}

class Horse extends Animal {
    move() {
        alert(this.name + " is Galloping...");
        super.move(45);
    }
}

var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");

sam.move();
tom.move(34);
  1. You don't need to manually assign the name to a public variable. Using public namein the constructor definition does this for you.

  2. You don't need to call super(name)from the specialised classes.

  3. Using this.nameworks.

  1. 您不需要手动将名称分配给公共变量。public name在构造函数定义中使用为您完成此操作。

  2. 您不需要super(name)从专门的类中调用。

  3. 使用this.name作品。

Notes on use of super.

使用注意事项super

This is covered in more detail in section 4.9.2of the language specification.

这在语言规范的第 4.9.2 节中有更详细的介绍

The behaviour of the classes inheriting from Animalis not dissimilar to the behaviour in other languages. You need to specify the superkeyword in order to avoid confusion between a specialised function and the base class function. For example, if you called move()or this.move()you would be dealing with the specialised Snakeor Horsefunction, so using super.move()explicitly calls the base class function.

继承自的类Animal的行为与其他语言中的行为没有什么不同。您需要指定super关键字以避免在专用函数和基类函数之间混淆。例如,如果你调用了move()或者this.move()你将处理专门的SnakeHorse函数,那么使用super.move()显式调用基类函数。

There is no confusion of properties, as they are the properties of the instance. There is no difference between super.nameand this.name- there is simply this.name. Otherwise you could create a Horse that had different names depending on whether you were in the specialized class or the base class.

没有混淆属性,因为它们是实例的属性。super.name和之间没有区别this.name- 很简单this.name。否则,您可以创建具有不同名称的 Horse,具体取决于您是在专用类中还是在基类中。

回答by Willem van der Veen

You are incorrectly using the superand thiskeyword. Here is an example of how they work:

您错误地使用了superandthis关键字。以下是它们如何工作的示例:

class Animal {
    public name: string;
    constructor(name: string) { 
        this.name = name;
    }
    move(meters: number) {
        console.log(this.name + " moved " + meters + "m.");
    }
}

class Horse extends Animal {
    move() {
        console.log(super.name + " is Galloping...");
        console.log(this.name + " is Galloping...");
        super.move(45);
    }
}

var tom: Animal = new Horse("Tommy the Palomino");

Animal.prototype.name = 'horseee'; 

tom.move(34);
// Outputs:

// horseee is Galloping...
// Tommy the Palomino is Galloping...
// Tommy the Palomino moved 45m.

Explanation:

解释:

  1. The first log outputs super.name, this refers to the prototype chainof the object tom, not the object tomself. Because we have added a name property on the Animal.prototype, horseee will be outputted.
  2. The second log outputs this.name, the thiskeyword refers to the the tom object itself.
  3. The third log is logged using the movemethod of the Animal base class. This method is called from Horse class move method with the syntax super.move(45);. Using the superkeyword in this context will look for a movemethod on the prototype chain which is found on the Animal prototype.
  1. 第一个日志输出super.name,this指的是对象的原型链tom,而不是对象tom自身。因为我们在 上添加了 name 属性Animal.prototype,所以会输出horseee。
  2. 第二个日志输出this.namethis关键字指的是tom对象本身。
  3. 第三个日志是使用moveAnimal 基类的方法记录的。该方法是从 Horse 类的 move 方法中调用的,语法为super.move(45);super在此上下文中使用关键字将move在原型链上查找一个方法,该方法可在 Animal 原型上找到。

Remember TS still uses prototypes under the hood and the classand extendskeywords are just syntactic sugar over prototypical inheritance.

请记住,TS 仍然在幕后使用原型,class并且extends关键字和关键字只是原型继承上的语法糖。