原型继承 - 正确的方法

时间:2010-01-16 19:19:52

标签: javascript

根据道格拉斯·克罗克福德的说法,我一直在研究用JavaScript做正确的原型方式继承:http://javascript.crockford.com/prototypal.html

他写道:“因此,不是创建类,而是创建原型对象,然后使用对象函数创建新实例”

我认为这是做到这一点的方法:

var objA = {
    func_a : function() {
        alert('A');
    }
};

var objB = Object.create(objA);
objB.func_a = function() {
   alert('B');
}
objB.func_b = function() {
};


var objA_instance1 = Object.create(objA);
var objA_instance2 = Object.create(objA);
var objB_instance1 = Object.create(objB);
var objB_instance2 = Object.create(objB);
etc...

但是这不意味着现在有四个func_a实例(因为它不是objA.prototype的一部分,它只是“内部”),或者我不能正确理解这个?

另外,有什么方法可以达到函数的重写函数(例如在objB.func_a中调用objA.func_a)?

提前致谢。

2 个答案:

答案 0 :(得分:3)

func_a只有一个实例,它在objA上定义,这是因为Crockford的Object.create方法仅使用该对象(objA)作为新对象的原型:

console.log(objA_instance1.func_a == objA .func_a); // true
console.log(objA_instance2.func_a == objA .func_a); // true
您的objA_instances上的

func_a是由原型链到达的,对象并不真正拥有该属性:

console.log(objA_instance1.hasOwnProperty('func_a')); // false
console.log(objA_instance2.hasOwnProperty('func_a')); // false

答案 1 :(得分:2)

您将构造函数的prototype属性与对象的内部 [[Prototype]] 属性混淆,后者无法访问(FF使其可用作__proto__ );使用Object.create()将此内部属性设置为其参数,因此objAobjB将是“实例”对象的实际原型,即不会复制任何函数对象。

要调用被覆盖的函数,请通过例如objA.func_a访问它们并使用call()apply()在特定实例上使用它们,例如

objB.func_a = function() {
    objA.func_a.call(this); // call overridden method with current `this`
};