【问题标题】:Prototypal inheritence - the correct way原型继承——正确的方式
【发布时间】:2010-01-16 19:19:51
【问题描述】:

根据 Douglas Crockford 的说法,我一直在研究以正确的原型方式在 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)?

提前致谢。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    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
    

    【讨论】:

      【解决方案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`
      };
      

      【讨论】:

      • [[Prototype]] 可以通过 Object.getPrototypeOf(object) 访问,尽管它是 ES5-only。
      猜你喜欢
      • 2015-08-05
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      相关资源
      最近更新 更多