2014-11-20 3 views
9

В настоящее время я работаю над проектом, где мы пишем объектно-ориентированный JavaScript. В этом проекте я видел два различных способа определения класса:Использование прототипа JavaScript - лучшая практика

1: Объявить функции сразу на прототипе

My.Namespace.ClassName = function(param1, param2) { 
    this.member1 = param1; 
    this.member2 = param2; 
}; 

My.Namespace.ClassName.prototype = { 
    myFunction1: function() { 
     return this.member1 + " " + this.member2; 
    }, 

    myFunction2: function(param1) { 
     this.member3 = paraml; 
    } 
}; 

2: Подготовка каждой функцию человека на прототипе

My.Namespace.ClassName = function(param1, param2) { 
    this.member1 = param1; 
    this.member2 = param2; 
}; 

My.Namespace.ClassName.prototype.myFunction1 = function() { 
    return this.member1 + " " + this.member2; 
}; 

My.Namespace.ClassName.prototype.myFunction2 = function(param1) { 
    this.member3 = paraml; 
}; 

Есть ли какая-то разница в том, как работает JavaScript на основе двух приведенных примеров или это только разница в стиле?

Лично я не видел никаких различий в поведении, но у меня такое ощущение, что должна быть тонкая разница, которой я сейчас не хватает.

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

ответ

8

Существует тонкая разница. В первом методе, когда вы перезаписываете прототип, там было свойство, которое теперь потеряно. Это constructor, который указывает на вашу функцию. Конструктор позволяет вам воссоздать тип объекта, которым он является.

Вы можете легко получить его обратно, и поэтому использовать первый метод, вручную установив его:

My.Namespace.ClassName.prototype = { 
    myFunction1: function() { 
     return this.member1 + " " + this.member2; 
    }, 

    myFunction2: function(param1) { 
     this.member3 = paraml; 
    }, 
    constructor: My.Namespace.ClassName 
}; 

Смотрите также: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

+0

Можете ли вы объяснить более подробно, что вы имеете в виду с _in первый метод, когда вы перезаписываете прототип, там есть свойство, которое теперь потеряно. Вы имеете в виду, что существует разница в 'My.Namespace.ClassName.constructor' до и после вызова' var obj = new My.Namespace.ClassName ("value1", "value2") '? – hwcverwe

+0

Нет - 'My.Namespace.ClassName.prototype' поставляется с свойством' constructor'. Когда вы перезаписываете прототип, конструктор теряется. – Scimonster

+0

Принимается, но один вопрос: могу ли я объединить оба стиля или это вызовет проблемы? – hwcverwe