JavaScript 对象原型未通过工厂返回

JavaScript Object prototype not returned via Factory

本文关键字:工厂 返回 对象 原型 JavaScript      更新时间:2023-09-26

我已经设法创建了一个名为"createHumanByGender"的"类似工厂"的函数,但是,返回的对象不允许我将其原型方法称为"Human.prototype.getFullName()"。会有什么原因吗?

代码如下:

// get female instance of Jade
var jade = createHumanByGender.bind( this, 'Female', 'Jade', 'Taylor' )();
console.log( jade.getFullName() );

// ------------------------------------------------
// HUMAN
function Human ( forename, surname ) {
    this.forename = forename;
    this.surname = surname;
    this.age = 0;
}
Human.prototype = {
    getForename : function () {
        return this.forename;
    },
    getSurname : function () {
        return this.surname;
    },
    getFullName : function () {
        return this.forename + ' ' + this.surname;
    }
};

// MALE
function Male ( forename, surname ) {
    Human.call( this, forename, surname );
    this.gender = 'Male';
}
Male.prototype = Object.create( Human.prototype );

// FEMALE
function Female ( forename, surname ) {
    Human.call( this, forename, surname );
    this.gender = 'Female';
}
Female.prototype = Object.create( Human.prototype );

// GENDER
function createHumanByGender ( gender, forename, surname ) {
    return new this[gender]( forename, surname );
}

在代码中,在代码运行之前调用构造函数来分配prototype,因此对象没有从原型继承方法。 将对工厂函数的调用移到构造函数的定义之后。

此外,以您使用的方式使用this通常是一种不好的做法,因为它可能无法在严格模式下工作。 要么直接引用你想要的window,要么将构造函数作为某个命名空间对象的属性,并直接在该对象上查找它们。

此版本的代码有效(此处为工作演示):

// ------------------------------------------------
// HUMAN
function Human ( forename, surname ) {
    this.forename = forename;
    this.surname = surname;
    this.age = 0;
}
Human.prototype = {
    getForename : function () {
        return this.forename;
    },
    getSurname : function () {
        return this.surname;
    },
    getFullName : function () {
        return this.forename + ' ' + this.surname;
    }
};

// MALE
function Male ( forename, surname ) {
    Human.call( this, forename, surname );
    this.gender = 'Male';
}
Male.prototype = Object.create( Human.prototype );

// FEMALE
function Female ( forename, surname ) {
    Human.call( this, forename, surname );
    this.gender = 'Female';
}
Female.prototype = Object.create( Human.prototype );

// GENDER
function createHumanByGender ( gender, forename, surname ) {
    var f = this[gender];
    return new f( forename, surname );
}
// get female instance of Jade
var jade = createHumanByGender.bind( this, 'Female', 'Jade', 'Taylor' )();
console.log( jade.getFullName() );

仅供参考,我建议您将工厂函数更改为:

// GENDER
function createHumanByGender ( gender, forename, surname ) {
    var f = window[gender];
    return new f( forename, surname );
}

然后,像这样称呼它:

// get female instance of Jade
var jade = createHumanByGender('Female', 'Jade', 'Taylor');
console.log( jade.getFullName() );

仅供参考,如果您真的想在要立即调用的函数中引起this值,请使用.call()而不是.bind() - 但这里都不需要。