2015-03-25 4 views
2

У меня проблема с пониманием наследования и конструкторов javascript, несмотря на руководства, такие как https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript и http://robotlolita.me/2011/10/09/understanding-javascript-oop.html.Javascript: Наследовать форму прототипа без переопределения конструктора

Я хотел бы создать прототип и детей, унаследовавших его. Прототип имеет конструктор (или, другими словами, является функцией). Я хочу, чтобы дети наследовали этот конструктор, а не переопределяли конструктор для каждого ребенка. Конструктор родителя собирается делать довольно много вещей, код, для которого я не хочу дублировать в своих дочерних элементах. И даже список аргументов для конструктора может измениться, и в этом случае я хотел бы только изменить их в родительском конструкторе, а не каждом дочернем.

Так пример, который работает на jsfiddle (также см https://jsfiddle.net/9pj1avjh/10/):

Сначала преамбула выполнения тестов и несколько функций, чтобы сохранить печатая (пропустить):

function sayHello2(msg,name){ 
    document.write(name+": "+msg+" "+this.url+"<br />"); 
} 

function runtest(){ 
    var c = new child('google.com'); 
    c.sayHello("Website:","dolf"); 

    var p = new proto("yahoo.com"); 
    p.sayHello("Website:"); 

    document.write("<br />"); 

} 

Определить прототип/родитель:

var proto = function(url){ 
    this.url = url 
} 
proto.prototype.sayHello = function(msg){ 
    document.write(msg+" "+this.url+"<br />") 
} 

Это мясо. Он показывает желаемое поведение, но это означает, что мне всегда нужно переопределять конструктор в каждом дочернем элементе, чего я не хочу.

var child = function(url){ 
    this.url = url 
} 
child.prototype = Object.create(proto.prototype); 
child.prototype.sayHello = sayHello2 
runtest() 

Это больше похоже на то, что я хочу по коду, но не поведением. Этот случай вызывает this.url неопределен в ребенка:

var child = function(){ 
} 
child.prototype = Object.create(proto.prototype); 
child.prototype.constructor = proto.prototype.constructor 
child.prototype.sayHello = sayHello2 
runtest() 

И это тоже не работает, потому что он вызывает sayHello2 также использоваться на прото вместо просто ребенка

var child = proto.prototype.constructor 
child.prototype = Object.create(proto.prototype); 
child.prototype.sayHello = sayHello2 
runtest() 
+0

Я извиняюсь, я прочитал вопрос трижды ... Я до сих пор не мог понять. – thefourtheye

+0

@thefourtheye Я думаю, что OP хотел не переназначить 'this.url = url' внутри дочернего конструктора. –

ответ

3

Он принимает некоторое время, чтобы понять, что вы имели в виду, переопределив конструктор. То, что вы хотите сделать, - вызвать конструктор родителя при создании экземпляра дочернего элемента.

Так вы не хотите этого, то есть переназначения this.url = url, правильно?

var child = function(url, anotherFancyArg){ 
    this.url = url; 
    this.anotherFancyArg = anotherFancyArg; 
} 

ли это вместо:

var child = function(url, anotherFancyArg){ 
    proto.apply(this, arguments); 
} 

Теперь вы можете получить доступ к URL и anotherFancyArg внутри экземпляра ребенка с помощью этой ссылки: this.url, this.anotherFancyArg, например,

var c = new child('google.com', 'abc'); 
console.log(c.url); // you get google.com here 

Еще одна вещь, которую я заметил. Это неправильно:

child.prototype = Object.create(proto.prototype); 
child.prototype.constructor = proto.prototype.constructor; 

ли это вместо:

child.prototype = Object.create(proto.prototype); // you inherit from parent's prototype 
child.prototype.constructor = child; // but you instantiate the child object 
+0

Спасибо, это действительно то, что мне нужно. «Аргументы» и метод применения - это то, что мне нужно. –

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