#javascript #oop #this
#javascript #ооп #это
Вопрос:
Допустим, у меня есть конструктор Alpha:
//[#1]
Alpha = function(a,b){
attrib1 = a;
attrib2 = b;
};
атрибуты 1 и attrib2 должны иметь разное значение для каждого отдельного экземпляра.
Обычным решением было бы переключить attrib1 и attrib2 с помощью this.attrib1 и this.attrib2, однако, поскольку мы находимся внутри конструктора, объекта пока нет, и вызывать это не имело бы особого смысла (я знаю, что большинство браузеров, вероятно, приняли бы это в любом случае, но дело не в этом).
Первый вопрос: являются ли attrib1 и attrib2 (как показано в примере) локальными для конструктора? Я довольно новичок в Javascript и его прототипной системе.
Мое решение было бы:
//[#2]
Alpha = function(a,b){
attrib1 = a;
attrib2 = b;
};
Alpha.attrib1 = undefined;
Alpha.attrib2 = undefined;
Но тогда откуда конструктор знает, что я имею в виду атрибуты объекта, а не какие-то локальные переменные, называемые attrib1 и attrib2, поскольку я объявляю конструктор перед атрибутами? Разве это решение не было бы плохим, потому что я должен объявить атрибуты как Alpha.prototype.attrib1 и Alpha.prototype.attrib2, поскольку они являются общими для всех объектов Alpha и их не нужно объявлять более одного раза?
Я знаю, что объектные литералы могли бы быть обходным путем, но я не хочу их использовать. Если бы я ссылался на переменные «класса», например:
//[#3]
Alpha = function(a,b){
Alpha.attrib1 = a;
Alpha.attrib2 = b;
}
Что бы произошло? Обычно это изменило бы значение класса attrib1 и attrib2, но поскольку в JS классы уже являются объектами, не будет ли это эквивалентно моему примеру # 1, с той разницей, что каждый экземпляр Alpha будет начинаться с атрибутов attrib1 и attrib2, установленных независимо от того, что им установил предыдущий конструктор? Или, может быть, это будут делать только члены, объявленные как Alpha.prototype.attrib, поскольку копируется именно прототип?
Обычно я программист на C , и мне жаль, если это глупый вопрос, однако я хотел бы узнать об этом больше, прежде чем писать что-то слишком масштабное с помощью JS. Спасибо за чтение.
Ответ №1:
Я думаю, вы хотите сделать следующее:
Alpha = function(a, b) {
this.a = a;
this.b = b;
}
var alpha1 = new Alpha(1, 2);
var alpha2 = new Alpha(3, 4);
console.log('alpha1: ' alpha1.a ', ' alpha1.b); // prints alpha1: 1, 2
console.log('alpha2: ' alpha2.a ', ' alpha2.b); // prints alpha1: 3, 4
Ключом является new
ключевое слово: вызов функции, которому предшествует new
ключевое слово, действует как конструктор. Внутри функции this
будет ссылаться на вновь созданный объект.
Ответ на ваш первый вопрос: Нет, attrib1 и attrib2 не являются локальными для конструктора. Это глобальные переменные. Чтобы сделать ваши переменные локальными для функции, всегда используйте var
ключевое слово ( var attrib1 = a;
).
Комментарии:
1. Я знаю, как создать новый объект, вопрос был не в этом. Мой вопрос возникает из-за того факта, что в таких языках, как C , ссылка на указатель this в конструкторе принимается большинством компиляторов, но незаконна и небезопасна, поэтому я спрашивал, было ли то же самое в JS, и, если да, есть ли какие-либо альтернативы. Я знаю, что ваш пример работает, но, как программист на C , я просто немного неохотно отношусь к использованию этого в конструкторе. Но в любом случае спасибо за ответ.
2. В прототипе объектной модели в JS это простой способ объявления атрибутов объекта (переменной экземпляра). Я понимаю ваши чувства программиста на C , но это обычный шаблон в JS (вы увидите, что JS отличается от традиционных классических языков, таких как C или Java).
3. Что ж, тогда все установлено. Javascript действительно испорченный язык, и сегодня ночью мне будут сниться кошмары. Спасибо за ответ.