2014-02-16 3 views
1

В JavaScript, определяя classlike (конструктор) метод функции обычно делается так:Использование «this.prototype» против внешнего «constructor.prototype» в ООП

function Class1() { 
    // ... code ... 
} 
Class1.prototype.method1 = function(args) { 
    // ... code ... 
}; 

И идя общий синтаксис/семантика правил ECMAScript, нет никаких причин, я не мог отменить/изменить/продлить первоначальный Object.prototype с

function Class1() { 
    // ... code ... 
    this.prototype.method1 = function(args) { 
     // ... code ... 
    }; 
} 

Тогда почему это не сделано таким образом? Код выглядел бы немного более запутанным, но намного быстрее и чище писать и читать (помещая все методы, связанные с Class1, прямо под Class1). Разве это не было бы лучше использовать?

+2

Ваш второй пример кода не будет работать. Значение 'this' внутри конструктора * не * функция-конструктор; это значение вновь созданного объекта. – Pointy

+0

Тогда я мог бы получить доступ к нему через 'this.constructor'? Я мог бы также отредактировать мой вопрос. – gchiconi

+0

Конструктор запускается для * каждого * объекта, созданного экземпляром. Вы добавляете новый набор идентичных функций к своему прототипу каждый раз, когда вы строите новый объект, который имеет очень большие последствия для производительности. – meagar

ответ

2

Эти две части кода наиболее определенно не те же самые; второй не будет работать.

Что происходит в конструкторе (обычно) не имеет ничего общего с объектом-прототипом. Это код инициализации для каждого экземпляра. Предложенное свойство «прототипа» является «прототипом» свойства функции-конструктора, а не экземпляров.

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

+0

Правильно, я думаю, я его сейчас получаю. Благодаря! – gchiconi

2

Проблема в том, что эти два примера кода не являются эквивалентными. В первом примере «this» относится к Class1, но во втором примере «this» относится к тому, что только что создавал новый объект. Например,

var myObj = new Class1() 

в приведенном выше примере, это «myObj», который разбивает ваш второй пример.

Кроме того, даже если это сработало, вы будете воссоздать этот метод для каждого экземпляра, который вы сделали. Было бы гораздо эффективнее не делать этого.

1

Как указывалось в других ответах, второе использование прототипа не является допустимым кодом JavaScript, но кажется, что вы хотите иметь доступ к своему конструктору, когда он фактически запущен, что возможно с помощью этих двух опций:

1- если вы не используете строгий режим, вы можете иметь его любит:

var MyClass = function ClassConstructor(){ 
     arguments.callee.prototype. ... 
    } 

2- в строгом режиме, например, если у вас есть функция classlike как:

var MyClass = function ClassConstructor(){ 
     ClassConstructor.prototype. ... 
} 

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

1

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

Но они добавляются путем совместного использования той же копии метода/свойства.

Если он не был вызван прототипом: если он был назван «Боб» и переписывал от руки, было бы больше смысла:

var Bob = { 
    name : "Bob", 
    sayName: function () { 
     var person = this; 
     console.log("My name is " + person.name); 
    } 
}; 



var Person = function (name) { 
    var person = this; 
    person.name = name || Bob.name; 
    person.sayName = Bob.sayName; 
}; 


var doug = new Person("Doug"), 
    jim = new Person("Jim"); 

Там есть пара вещей происходит за кулисами, регулярно , но здесь здесь не так много различий, между Bob и тем, что обычно было бы Person.prototype.

Но вы можете четко видеть, почему вы не захотите сбросить имя Bob.name, каждый раз, когда вы создадите нового человека.

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