2013-10-15 2 views
1
// Sim.App - application class (singleton) 

    Sim.App = function() 
    { 
     this.renderer = null; 
     this.scene = null; 
     this.camera = null; 
     this.objects = []; 
    } 

    // Constructor 
    EarthApp = function() 
    { 
     Sim.App.call(this); 
    } 

// Subclass Sim.App 
EarthApp.prototype = new Sim.App(); 

==================================================================================================================================================================================== ========Попытка понять этот код в Javascript

В выше, я не понимаю, почему автор использовал это заявление

EarthApp.prototype = new Sim.App(); 

Он мог бы использовать

EarthApp = new Sim.App(); 

Пожалуйста, помогите мне понять использование «прототипа» в этом заявлении.

ответ

4

Прототипы являются основополагающим элементом в модели наследования Javascript. Я рекомендую вам прочитать об этом, потому что, не задумываясь, вы не получите «JS» полностью.

Учитывая, что определение объекта как прототипа функции делает этот объект в цепочке прототипов каждого экземпляра этой функции, созданной впоследствии.

Кстати цепочка прототипов работ (более или менее) (смотри пример ниже):

  1. Вы пытаетесь получить доступ к «Foo» переменную в объекте
  2. Если этот объект есть «Foo», возвращение это значение.
  3. Если у этого объекта нет «foo», посмотрите на его прототип (экземпляр «Sim.App» в вашем случае) - есть ли у него «foo»? Если да, верните его значение.
  4. Если прототип объекта не имеет «foo», посмотрите прототип прототипа - и так далее, через цепочку.

Если вы хотите узнать больше об этом, посмотрите at this article.

Пример - считай:

var Sim = {}; 
Sim.App = function() { 
    this.foo = 'sim'; 
} 

EarthApp = function() { 
} 

EarthApp.prototype = new Sim.App(); 

var earth = new EarthApp(); 

// I can access earth.foo even though 'earth' is an instance of 'EarthApp' 
// and not 'Sim.App'. That's because instance of 'Sim.App' is in 
// earth's prototype chain. 
console.log(earth.foo); 
+0

Почему 'console.log (earth.var);' не должна быть 'console.log (earth.prototype.var)'? или я что-то упускаю. – Nunners

+0

@Nunners - нет, 'earth.var' действительно - из-за того, как работает прототип цепи - см. Мой обновленный ответ. – kamituel

+0

Только что видел, спасибо за дополнительные детали и пояснения :) – Nunners

4

Линия

EarthApp.prototype = new Sim.App(); 

... Sim.App создает объект и присваивает его prototype свойству функции EarthApp. Это означает, что, когда мы делаем это:

var e = new EarthApp(); 

... объект e получите объект из EarthApp.prototype в качестве прототипа, придав ему доступ к свойствам и методам этого объекта.


FWIW, наследование осуществляется этот код на самом деле не является идеальным, потому что это вызов Sim.App конструктор для создания EarthApp.prototype объект, затем вызвать его снова для инициализации экземпляров. Если вы хотите цепи конструкторов вместе таким образом, вот более правильный способ сделать это:

// Reusable `derive` function 
// Set up `child`'s `prototype` property to be based on `parent`'s `prototype` property 
function derive(child, parent) 
{ 
    function ctor() 
    { 
    } 

    ctor.prototype = parent.prototype; 
    child.prototype = new ctor(); 
    child.prototype.constructor = parent; 
} 

// Sim.App - application class (singleton) 
Sim.App = function() 
{ 
    this.renderer = null; 
    this.scene = null; 
    this.camera = null; 
    this.objects = []; 
}; 

// Constructor 
EarthApp = function() 
{ 
    Sim.App.call(this); 
}; 

// Subclass Sim.App 
derive(EarthApp, Sim.App); 

Вы можете проверить мой Lineage вспомогательный скрипт, который делает выше и обрабатывает всю сантехнику, необходимую для обработки «суперклассы» правильно и таковые.

Следует также отметить, что это всего лишь один из способов использования прототипического наследования JavaScript, который чрезвычайно гибкий.

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