用另一个原型扩展原型

时间:2015-12-18 12:25:09

标签: javascript object prototype

我想用另一个Prototype扩展Prototype。这是我目前的代码,尝试了不同的东西,我无法让它工作。

Network.prototype是一个空对象,为什么?

function Tester() {}

Tester.prototype = {
	clazz: 'Tester',
	start: function (url) {}
};


function NetworkTester() {}

NetworkTester.prototype = {
	clazz: 'NetworkTester',
        test: function (url) {
           this.start(); // this is undefined
        }
};


var helpers = {
    extend2: function (ChildClass, ParentClass) {
		ChildClass.prototype = new ParentClass();
		ChildClass.prototype.constructor = ChildClass;
	}
};

helpers.extend2(NetworkTester, Tester);

console.log(NetworkTester.prototype);

我不想写这样的NetoworkTester代码:

NetworkTester.prototype.clazz = 'NetworkTester';
NetworkTester.prototype.test = function (url) {
    this.start(); // this is undefined
};

我想拥有它,它更漂亮。

1 个答案:

答案 0 :(得分:1)

为什么会这样?

因为您使用以下行覆盖.prototype属性:

ChildClass.prototype = new ParentClass();

new ParentClass();创建的对象是一个没有任何属性的对象(因为你没有在Tester的构造函数中赋值),因此它在开发工具中显示为一个空对象

虽然设置了[[Prototype]]的内部NetworkTester.prototype广告位。您可以使用Object.getPrototypeOf方法查看它:

Object.getPrototypeOf(NetworkTester.prototype)

如何解决这个问题?

要解决您的困境,您必须转变代码顺序:

  1. 为子项的.prototype属性创建新对象,并将其链接到父项:

    helpers.extend2(NetworkTester, Tester);
    
  2. 定义子项的.prototype属性:

    NetworkTester.prototype.x = ...;
    NetworkTester.prototype.y = ...;
    
  3. 为了避免对父项进行不必要的构造函数调用,您应该使用Object.create而不是new运算符。

    所以你的代码看起来像这样:

    var helpers = {
        extend2: function (ChildClass, ParentClass) {
            ChildClass.prototype = Object.create(ParentClass.prototype);
            ChildClass.prototype.constructor = ChildClass;
        }
    };
    
    function Tester() {}
    
    Tester.prototype = {
        clazz: 'Tester',
        start: function (url) {}
    };
    
    
    function NetworkTester() {}
    
    // This needs to happen before you assign to NetworkTester.prototype
    helpers.extend2(NetworkTester, Tester);
    
    NetworkTester.prototype.clazz = 'NetworkTester';
    NetworkTester.prototype.test = function (url) {
        this.start(); // this is undefined
    };
    
    console.log(NetworkTester.prototype);