2015-07-25 5 views
2

Я хотел бы добавить метод «bar» к родительскому классу A, после, подкласс B определен, так что метод наследуется. Является ли это возможным?Javascript: Добавление метода к родительскому классу/для унаследования

Я попытался следующий код

function A() { 
    this.foo = function() { 
     console.log('foo') 
    } 
} 
function B() { 
    A.call(this) 
} 

// (trying to) add a new method to A 

A.prototype.bar = function() { 
    console.log('bar'); 
} 

// It works with instances of A 
var a = new A()  
a.foo()   // ok 
a.bar()   // ok 

// but not with an instance of B 
var b = new B()  
b.foo()   // this works 
b.bar()   // not this one <------ 

/* 
    Exception: b.bar is not a function 
    @Scratchpad/3:17:1 
*/ 

Любые предложения, пожалуйста?

+0

хорошо, потому что '' Ā' и b' не являются экземплярами одного и того же класса .. –

+0

вы можете сделать 'Object.prototype.bar = функция () {..} ', чтобы добавить его в * все * объекты, но эта кисть может быть намного шире, чем вы хотите –

ответ

1

Если вам нужно просто исправить код, вы можете связать методы, как это:

function B() { 
    A.call(this) 
    for(var i in A.prototype){ this[i] = A.prototype[i]; } 
} 

Но я думаю, что это плохой способ.

1
function A() { 
    this.foo = function() { 
     console.log('foo'); 
    }; 
} 
function B() { 
    A.call(this); 
} 

// (trying to) add a new method to A 

A.prototype.bar = function() { 
    console.log('bar'); 
}; 
B.prototype = Object.create(A.prototype); 
// It works with instances of A 
var a = new A() ; 
a.foo() ;   // ok 
a.bar() ;   // ok 

// but not with an instance of B 
var b = new B() ;  
b.foo() ;   // this works 
b.bar() ; 

I случай функционального типа наследования - вы не можете добавлять методы, которых нет в классе. Используйте прототипы

+0

Или' Object.setPrototypeOf() ', но это для новых браузеров :-) –

+0

@RoyiNamir здесь qoute - Если вы заботитесь о производительности, вам следует избегать установки [[Prototype]] объекта. Вместо этого создайте новый объект с желаемым [[Prototype]], используя Object.create(). - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf – shabunc

+0

@shabunc Да. но продолжайте читать: _Object.setPrototypeOf() находится в последнем стандартном черновике ECMAScript 6. Обычно считается правильным способом установить прототип объекта по сравнению с более противоречивым Object.prototype .__ proto__ property._ Я думаю, что красное предупреждение в начале говорит о '__proto__' thingy. Хорошо ... Я все равно поеду со стандартом. –

0

Вы упускаете:

B.prototype.__proto__ = A.prototype 

Если вам не нравится с помощью __proto__ вы можете использовать:

B.prototype = Object.create(A.prototype); 
+0

Установка '__proto__' не рекомендуется (я не dv) –

+0

@RoyiNamir true, вы также можете использовать' Object.create() ', я думаю,' __proto__' - это старая школа: p – danillouz

+0

Да :-). Я не думаю, что это когда-нибудь будет на 100% устаревшим. –

1
// if you define the prototype as an object 
var A = { 
    foo: function() { 
     console.log('foo'); 
    } 
}; 

// and define constructors using Object.create 
function newA() { 
    return Object.create(A); 
}; 

function newB() { 
    return Object.create(newA()); 
}; 

// you can add methods to the prototype 
A.bar = function() { 
    console.log('bar'); 
}; 

// it works with instances of A 
var a = newA()  
a.foo(); 
a.bar(); 

// and instances of B 
var b = newB(); 
b.foo(); 
b.bar(); 

// you can even modify the prototype after the fact 
A.baz = function() { 
    console.log('baz'); 
}; 

// and that will work as well 
a.baz(); 
b.baz(); 

http://jsfiddle.net/5s8ahvLq/

Если вы не хотите, чтобы последнее поведение было в состоянии отредактировать protoype после факта, используйте Object.assign или что-то подобное подчеркивание или lodash, который обеспечивает эту функциональность:

function newA() { 
    return Object.create(Object.assign({}, A)); 
} 
+0

Кажется, это то, что я искал. Большое спасибо всем. –

+0

Не можете ли вы переопределить некоторые вещи в подклассе и использовать статический метод в родительском классе? Вызывающая панель A и B of A отдельно –

+0

Боюсь, я не понимаю. Не могли бы вы объяснить, что вы имеете в виду? –

Смежные вопросы