Javascript: конструктор, это и область видимости

#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 действительно испорченный язык, и сегодня ночью мне будут сниться кошмары. Спасибо за ответ.