2014-12-23 2 views
0

Я работаю с довольно большим проектом JavaScript и пытаюсь реорганизовать его, чтобы убедить его вести себя в большей части метода JavaScripty. Одна вещь, которую я действительно хочу внести, - это сделать наследование доступным, так как это очень хорошо подходит для большей части моей работы, но, похоже, немного сложно использовать прототипы и наследование таким образом, чтобы их было легко читать и следовать не растворяясь в jam jam.Создание чистых, наследуемых объектов в JavaScript

я должен что-то вроде этого:

MyMammal = function(name) { 
    if (0 < arguments.length) 
    { 
     this.init(name); 
    } 
} 
MyMammal.prototype= { 
    init: function(name) { 
     this.name= name; 
    }, 

    getName: function() { 
     return this.name; 
    } 
} 

Тогда для классов, которые вытекают из MyMammal Я работаю так:

MyDog = function(name, breed) { 
    if (0 < arguments.length) 
    { 
     this.init(name, breed); 
    } 
} 
MyDog.prototype = Object.create(MyMammal.prototype); 

_.extend(MyDog.prototype, { 
    init: function(name, breed) 
    { 
     this.name = name; 
     this.breed = breed; 
    }, 

    getBreed: function() 
    { 
     return this.breed; 
    } 
}); 

Теперь это работает постольку, поскольку я получаю исходы I ожидайте от вызовов методов, но JavaScript, похоже, не знает, что MyMammal является прототипом MyDog, если я пытаюсь использовать isPrototypeOf, хотя он признает, что экземпляр MyDog является instanceof MyMammal.

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

+0

Хороший код, откуда _.extend пришел. IE11 не поддерживает это – Mouser

+0

@Mouser '_' является библиотекой underscore или lodash –

+0

@Mouser, которая является частью Underscore (http://underscorejs.org/#extend), которая является одной из библиотек, с тех пор как я начал ее использовать. I не может жить без ... – glenatron

ответ

1

Это, например:

MyMammal = function(name) { 
    if (0 < arguments.length) 
    { 
     this.init(name); 
    } 
} 
MyMammal.prototype= { 
    init: function(name) { 
     this.name= name; 
    }, 

    getName: retrieveNameOfMammal}; //here is where the fun happens 

function retrieveNameOfMammal() 
{ 
    return this.name; 
} 

MyDog = function(name, breed) { 
    MyMammal.apply(this, name); //this will apply all properties and functions from MyMammal, so you do not have to recreate this.init every time. 
} 
+0

Разве это не то, что происходит, добавляя их к прототипу? Я понял, что функции прототипа разделяются между экземплярами, но функции-члены функции не являются. Итак, если бы у меня была функция в «MyMammal», которая была бы для каждого экземпляра, но в «MyMammal.prototype» все экземпляры «MyMammal» могли бы принять участие в этом? – glenatron

+0

Правда, 'getName' доступен для каждого экземпляра и для каждого экземпляра тот же и только один раз создается. Тем не менее этот способ обеспечивает более читаемый код :-) – Mouser

+0

Рассмотрите это изменение. – Mouser