簡體   English   中英

使用JavaScript的原型繼承鏈

[英]Prototypal inheritance chain with JavaScript

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}
Person.prototype.talk = function () {
    return this.firstName + " " + this.lastName;
}
//creating a Person object for extension
var manager = new Person('jon', 'doe');
console.log(manager.talk());
//Manager prototype..but doesn't inherit Person methods 
function Manager(firstName, lastName, accessCode) {
    //shared properties
    this.firstName = firstName;
    this.lastName = lastName;

    this.accesscode = accessCode;
}
function personChecker(person) {
    var returnCode = 0;
    if (person instanceof Person) {
        returnCode = 1;
    }
    else if (person instanceof Manager) {
        returnCode = 2;
    }
    return returnCode;
}
console.log(personChecker(manager));

是否可以共享原型並擁有不同的構造函數? 我想讓Manager從Person繼承所有內容(然后擴展它),並在原型上進行功能切換,並根據傳遞給personChecker函數的參數執行不同的personChecker

支持這種繼承的典型方法:

// create a blank function to pass the prototype
var blank = function() {};

// assign the prototype to inherit to the blank constructor
blank.prototype = Person.prototype;

// pass an instance of the prototype as the Manager prototype
Manager.prototype = new blank();

var person = new Person('John', 'Doe');
var manager = new Manager('Greg', 'Smith', 'access1234');

manager.talk(); // Greg Smith
person.talk(); // John Doe

這是一個小提琴: http : //jsfiddle.net/XF28r/

請注意,經理也是人,因此您需要切換支票。

function personChecker(person) {
    var returnCode = 0;
    if (person instanceof Manager) {
        returnCode = 2;
    } else if (person instanceof Person) {
        returnCode = 1;
    }
    return returnCode;
}

盡管注意,我會將其放在輔助方法中:

function extend(parent, child) {

  var blank = function() {};
  blank.prototype = parent.prototype;
  child.prototype = new blank();
}

因此,您可以簡單地使用它:

extend(Person, Manager);

正如Bergi在評論中提到的那樣,這也可以簡化為:

function extend(parent, child) {
  child.prototype = Object.create(parent.prototype);
}

(適用於IE 9或更高版本)

在JavaScript中,繼承通常是這樣完成的:

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

Object.create創建一個新對象,並將該對象作為其原型鏈中的第一個參數傳遞。

如果您需要支持沒有Object.create舊瀏覽器,則可以執行“原型舞蹈”:

function F(){}
F.prototype = Person.prototype;
Manager.prototype = new F();

無論如何,避免代碼調用構造函數來獲取這樣的對象( Manager.prototype = new Person() ),這是眾所周知的反模式,一旦構造函數依賴於其任何參數,它就會中斷(並且會導致其他更細微的問題)。

使用以下內容:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}
Person.prototype.talk = function () {
    return this.firstName + " " + this.lastName;
}

function Manager(firstName, lastName, accessCode) {
    //shared properties
    this.firstName = firstName;
    this.lastName = lastName;

    this.accesscode = accessCode;
}
Manager.prototype = new Person('jon', 'doe');

function personChecker(person) {
    var returnCode = 0;
    if (person instanceof Manager) {
        returnCode = 2;
    }
    else if (person instanceof Person) {
        returnCode = 1;
    }
    return returnCode;
}

請注意,我更改了條件語句的順序,因為Manager的實例也是Person的實例:

var per = new Person('A', 'B');
per.talk();              // 'A B'
per instanceof Person;   // true
per instanceof Manager;  // false
personChecker(per);      // 1

var man = new Manager('A', 'B');
man.talk();              // 'A B'
man instanceof Person;   // true !!!!
man instanceof Manager;  // true !!!!
personChecker(man);      // 2

如果你想做的好方法,而不是

Manager.prototype = new Person('jon', 'doe');

采用

Manager.prototype = Object.create(Person.prototype, {constructor: {value: Manager}});

但它不適用於舊的瀏覽器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM