2013-05-16 42 views
2
var a = function(){ 
    this.sayFoo = function(){ 
     console.log('foo'); 
    }; 
} 

var b = function(){ 
    console.log(this.prototype); //undefined 
    this.sayBar = function(){ 
     console.log('bar'); 
    }; 
} 

b.prototype = new a(); 

var bInst = new b(); 

bInst.sayFoo(); 
bInst.sayBar(); 

console.log(b.prototype); //a {sayFoo: function} 

http://jsfiddle.net/KbBny/1/内部构造函数原型设置

如何添加sayBarb原型构造函数里面?

b.prototype = new a();是否覆盖原型,或合并ba的?

+1

原型的整体思路是,你把它定义* *外的构造,而不是内部。 –

+0

阅读此:http://stackoverflow.com/a/8096017/783743 –

回答

1

是否b.prototype = new a();覆盖原型,或合并B的用的?

它用新的a实例覆盖它;没有合并(例如,您需要更新b.prototype.constructor属性)。这就是为什么你在这一行之后添加所有属性到b.prototype。然而,实际上你不希望创建一个实例,但刚刚成立的原型链中正确:

b.prototype = Object.create(a.prototype); 

如何添加sayBar给函数构造函数中的B原型?

你不应该把它添加到原型,因为它不是一个原型(共享)方法 - 它的实例,具体到每一个a实例(至少是应该的,否则你会把它放在a.prototype然后它被上面的线覆盖)。要获得所有b实例的实例方法,以及,你使用

var b = function(){ 
    a.call(this); // invoke the `a` constructor on this instance 
}; 
+0

嗯,不知道我是否在跟踪你的最后一部分。如果我在b construcor函数中使用'this.sayBar = ...',它必须为每个b的实例重新定义,对吧?将它添加到原型不是更好吗? – Johan

+1

@ alex23不,函数总是不在原型中。 – Alnitak

+0

@ alex23然后请解释为什么我不在控制台中看到两种方法:http://jsfiddle.net/KbBny/2/ – Johan

2

您没有使用正确的继承模式。

用途:

b.prototype = Object.create(a.prototype); 

在你的情况,你正在执行一个简单的覆盖,您没有正确建立继承。 Object.create是ES5,但你可以用这种填充工具:

的Object.create

if (!Object.create) { 
    Object.create = function (o) { 
     if (arguments.length > 1) { 
      throw new Error('Object.create implementation only accepts the first parameter.'); 
     } 
     function F() {} 
     F.prototype = o; 
     return new F(); 
    }; 
} 

访问原型

您不能访问prototype定义块内。你有一个this参考。

var b = function() { 
    a.call(this); 
    b.prototype.doSomething = function() {console.log("b");}; 
}; 
b.prototype = Object.create(a.prototype); 

DEMO

+0

这是否合并原型?那么浏览器如何支持'Object.create'? – Johan

+0

谢谢,是否足以包含'Object.create'的源代码以便在旧版浏览器中支持它?还是它依赖于其他功能? – Johan

+0

@Johan https://developer.mozilla。org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create#Polyfill –