简体   繁体   English

JavaScript 中的原型继承

[英]Prototypical inheritance in JavaScript

I am new to javascript's prototypical inheritance and js object-oriented programming.我是 javascript 原型继承和 js 面向对象编程的新手。 I was trying to create a base object, Account and then inherit the CheckingAccount from it.我试图创建一个基础对象 Account,然后从中继承 CheckingAccount。 The following is my code.以下是我的代码。

function Account(fName, lName) {
   this.firstName = fName;
   this.lastName = lName;

 }

 Account.prototype.balance = function() {
    console.log("This is the balance");
 }

 function CheckingAccount() {

    this.salary = 10000;
 }

 CheckingAccount.prototype = Object.create(Account.prototype);

 let account = new Account("John", "Doe");
 let checking = new CheckingAccount();
 CheckingAccount.balance();

When I run it on Visual Studio, I am getting the following error: "Uncaught TypeError: CheckingAccount.balance is not a function"当我在 Visual Studio 上运行它时,出现以下错误:“Uncaught TypeError: CheckingAccount.balance is not a function”

You want to call the method on the instance and not the Class object (eg, checking not CheckingAccount ).您想调用实例上的方法而不是 Class 对象(例如, checking不是CheckingAccount )。 Also, make sure to change the constructor.另外,请确保更改构造函数。 For further reading, refer to the MDN documentation .如需进一步阅读,请参阅MDN 文档

You can see these changes here:您可以在此处查看这些更改:

 function Account(fName, lName) { this.firstName = fName; this.lastName = lName; this.salary = 0; } Account.prototype.balance = function() { return this.salary; // you'll probably not use _only_ salary here } function CheckingAccount() { this.salary = 10000; } CheckingAccount.prototype = Object.create(Account.prototype); // Make sure to update the constructor Object.defineProperty(CheckingAccount.prototype, 'constructor', { value: CheckingAccount, enumerable: false, // so that it does not appear in 'for in' loop writable: true }); let account = new Account("John", "Doe"); let checking = new CheckingAccount(); console.log('account balance:', account.balance()) console.log('checking balance:', checking.balance()) console.log('account constructor:', account.constructor); console.log('checking constructor:', checking.constructor);

You can do this using the proper class keyword in ES6.你可以在 ES6 中使用适当的class关键字来做到这一点。 Here's an example of Account and Chequing which extends it.这是扩展它的帐户和支票的示例。 Here the Account class has a balance , deposit and showBook function, and only the child Chequing class has a writeCheque function.在这里, Account类有一个balancedepositshowBook功能,只有孩子Chequing类有一个writeCheque功能。 Yet the Chequing instance can still call all parent class functions since it's an Account .然而Chequing实例仍然可以调用所有父类函数,因为它是一个Account

 class Account { constructor(name) { this.name = name; this.amount = 0; } balance() { return this.amount } deposit(sum) { this.amount += sum; } showBook() { console.log("-------------------------"); console.log("Account for",this.name); console.log(`Balance: $${this.amount}`); } } class Chequing extends Account { constructor(name) { super(name); this.cheques = []; } writeCheque(sum, to) { this.amount -= sum; this.cheques.push({number: this.cheques.length+1, recipient: to, amount: sum}); } showBook() { super.showBook(); if (this.cheques.length > 0) { console.log("Cheque activity:"); for (const cheque of this.cheques) { console.log(` ${cheque.number}: $${cheque.amount} paid to ${cheque.recipient}`); } } else console.log("No cheques have been written"); } } const ch1 = new Chequing("Mary Jones"); ch1.deposit(1000); ch1.showBook(); ch1.writeCheque(95, "Bob Smith"); ch1.writeCheque(485, "Ritz Hotel"); ch1.showBook();

Account is class here.帐户是这里的类。 CheckingAccount is class too. CheckingAccount也是类。 the account and checking are instances.帐户支票是实例。

if you want the CheckingAccount to inherit from Account class, you should, and did this:如果您希望CheckingAccount继承自Account类,您应该这样做:

CheckingAccount.prototype = Object.create(Account.prototype);

This delegates CheckingAccount's prototype object to Accounts prototype object.这将 CheckingAccount 的原型对象委托给 Accounts 原型对象。

There is no balance property in CheckingAccount function ( functions are first-class objects in javascript ), there is only prototype property on it. CheckingAccount函数中没有balance属性(函数是 javascript 中的一等对象),上面只有prototype属性。 Though the balance property, which is the function same time, resides on the object, where Account's prototype property points to (balance function is inside of Account.prototype object in short) .虽然balance属性,同时也是函数,驻留在对象上,Account 的prototype 属性指向的对象(简称balance 函数在Account.prototype 对象内部)

The function balance() is accessible from:函数balance()可从以下位置访问:

  • Account.prototype Account.prototype
  • CheckingAccount.prototype (because of the Object.create function you used) CheckingAccount.prototype (因为你使用了 Object.create 函数)
  • From any instances of both these classes.从这两个类的任何实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM