Классы. Объектно-ориентированное программирование
Java является объектно-ориентированным языком, поэтому такие понятия как «класс» и «объект» играют в нем ключевую роль. Любую программу на Java можно представить как набор взаимодействующих между собой объектов.
Шаблоном или описанием объекта является класс , а объект представляет экземпляр этого класса. Можно еще провести следующую аналогию. У нас у всех есть некоторое представление о человеке — наличие двух рук, двух ног, головы, туловища и т.д. Есть некоторый шаблон — этот шаблон можно назвать классом. Реально же существующий человек (фактически экземпляр данного класса) является объектом этого класса.
Класс определяется с помощью ключевого слова сlass :
class Person
В данном случае класс называется Person. После названия класса идут фигурные скобки, между которыми помещается тело класса — то есть его поля и методы.
Любой объект может обладать двумя основными характеристиками: состояние — некоторые данные, которые хранит объект, и поведение — действия, которые может совершать объект.
Для хранения состояния объекта в классе применяются поля или переменные класса. Для определения поведения объекта в классе применяются методы. Например, класс Person, который представляет человека, мог бы иметь следующее определение:
class Person < String name; // имя int age; // возраст void displayInfo()< System.out.printf("Name: %s \tAge: %d\n", name, age); >>
В классе Person определены два поля: name представляет имя человека, а age — его возраст. И также определен метод displayInfo, который ничего не возвращает и просто выводит эти данные на консоль.
Теперь используем данный класс. Для этого определим следующую программу:
public class Program < public static void main(String[] args) < Person tom; >> class Person < String name; // имя int age; // возраст void displayInfo()< System.out.printf("Name: %s \tAge: %d\n", name, age); >>
Как правило, классы определяются в разных файлах. В данном случае для простоты мы определяем два класса в одном файле. Стоит отметить, что в этом случае только один класс может иметь модификатор public (в данном случае это класс Program), а сам файл кода должен называться по имени этого класса, то есть в данном случае файл должен называться Program.java.
Класс представляет новый тип, поэтому мы можем определять переменные, которые представляют данный тип. Так, здесь в методе main определена переменная tom , которая представляет класс Person. Но пока эта переменная не указывает ни на какой объект и по умолчанию она имеет значение null . По большому счету мы ее пока не можем использовать, поэтому вначале необходимо создать объект класса Person.
Конструкторы
Кроме обычных методов классы могут определять специальные методы, которые называются конструкторами . Конструкторы вызываются при создании нового объекта данного класса. Конструкторы выполняют инициализацию объекта.
Если в классе не определено ни одного конструктора, то для этого класса автоматически создается конструктор без параметров.
Выше определенный класс Person не имеет никаких конструкторов. Поэтому для него автоматически создается конструктор по умолчанию, который мы можем использовать для создания объекта Person. В частности, создадим один объект:
public class Program < public static void main(String[] args) < Person tom = new Person(); // создание объекта tom.displayInfo(); // изменяем имя и возраст tom.name = "Tom"; tom.age = 34; tom.displayInfo(); >> class Person < String name; // имя int age; // возраст void displayInfo()< System.out.printf("Name: %s \tAge: %d\n", name, age); >>
Для создания объекта Person используется выражение new Person() . Оператор new выделяет память для объекта Person. И затем вызывается конструктор по умолчанию, который не принимает никаких параметров. В итоге после выполнения данного выражения в памяти будет выделен участок, где будут храниться все данные объекта Person. А переменная tom получит ссылку на созданный объект.
Если конструктор не инициализирует значения переменных объекта, то они получают значения по умолчанию. Для переменных числовых типов это число 0, а для типа string и классов — это значение null (то есть фактически отсутствие значения).
После создания объекта мы можем обратиться к переменным объекта Person через переменную tom и установить или получить их значения, например, tom.name = «Tom» .
В итоге мы увидим на консоли:
Name: null Age: 0 Name: Tom Age: 34
Если необходимо, чтобы при создании объекта производилась какая-то логика, например, чтобы поля класса получали какие-то определенные значения, то можно определить в классе свои конструкторы. Например:
public class Program < public static void main(String[] args) < Person bob = new Person(); // вызов первого конструктора без параметров bob.displayInfo(); Person tom = new Person("Tom"); // вызов второго конструктора с одним параметром tom.displayInfo(); Person sam = new Person("Sam", 25); // вызов третьего конструктора с двумя параметрами sam.displayInfo(); >> class Person < String name; // имя int age; // возраст Person() < name = "Undefined"; age = 18; >Person(String n) < name = n; age = 18; >Person(String n, int a) < name = n; age = a; >void displayInfo() < System.out.printf("Name: %s \tAge: %d\n", name, age); >>
Теперь в классе определено три коструктора, каждый из которых принимает различное количество параметров и устанавливает значения полей класса.
Консольный вывод программы:
Name: Undefined Age: 18 Name: Tom Age: 18 Name: Sam Age: 25
Ключевое слово this
Ключевое слово this представляет ссылку на текущий экземпляр класса. Через это ключевое слово мы можем обращаться к переменным, методам объекта, а также вызывать его конструкторы. Например:
public class Program < public static void main(String[] args) < Person undef = new Person(); undef.displayInfo(); Person tom = new Person("Tom"); tom.displayInfo(); Person sam = new Person("Sam", 25); sam.displayInfo(); >> class Person < String name; // имя int age; // возраст Person() < this("Undefined", 18); >Person(String name) < this(name, 18); >Person(String name, int age) < this.name = name; this.age = age; >void displayInfo() < System.out.printf("Name: %s \tAge: %d\n", name, age); >>
В третьем конструкторе параметры называются так же, как и поля класса. И чтобы разграничить поля и параметры, применяется ключевое слово this:
this.name = name;
Так, в данном случае указываем, что значение параметра name присваивается полю name.
Кроме того, у нас три конструктора, которые выполняют идентичные действия: устанавливают поля name и age. Чтобы избежать повторов, с помощью this можно вызвать один из конструкторов класса и передать для его параметров необходимые значения:
Person(String name)
В итоге результат программы будет тот же, что и в предыдущем примере.
Инициализаторы
Кроме конструктора начальную инициализацию объекта вполне можно было проводить с помощью инициализатора объекта. Инициализатор выполняется до любого конструктора. То есть в инициализатор мы можем поместить код, общий для всех конструкторов:
public class Program < public static void main(String[] args) < Person undef = new Person(); undef.displayInfo(); Person tom = new Person("Tom"); tom.displayInfo(); >> class Person < String name; // имя int age; // возраст /*начало блока инициализатора*/ < name = "Undefined"; age = 18; >/*конец блока инициализатора*/ Person() < >Person(String name) < this.name = name; >Person(String name, int age) < this.name = name; this.age = age; >void displayInfo() < System.out.printf("Name: %s \tAge: %d\n", name, age); >>
Name: Undefined Age: 18 Name: Tom Age: 18
Конструктор, оператор «new»
Обычный синтаксис <. >позволяет создать только один объект. Но зачастую нам нужно создать множество похожих, однотипных объектов, таких как пользователи, элементы меню и так далее.
Это можно сделать при помощи функции-конструктора и оператора «new» .
Функция-конструктор
Функции-конструкторы технически являются обычными функциями. Но есть два соглашения:
- Имя функции-конструктора должно начинаться с большой буквы.
- Функция-конструктор должна выполняться только с помощью оператора «new» .
function User(name) < this.name = name; this.isAdmin = false; >let user = new User("Jack"); alert(user.name); // Jack alert(user.isAdmin); // false
Когда функция вызывается как new User(. ) , происходит следующее:
- Создаётся новый пустой объект, и он присваивается this .
- Выполняется тело функции. Обычно оно модифицирует this , добавляя туда новые свойства.
- Возвращается значение this .
Другими словами, new User(. ) делает что-то вроде:
function User(name) < // this = <>; (неявно) // добавляет свойства к this this.name = name; this.isAdmin = false; // return this; (неявно) >
Таким образом, let user = new User(«Jack») возвращает тот же результат, что и:
let user = < name: "Jack", isAdmin: false >;
Теперь, если нам будет необходимо создать других пользователей, мы можем просто вызвать new User(«Ann») , new User(«Alice») и так далее. Данная конструкция гораздо удобнее и читабельнее, чем многократное создание литерала объекта.
Это и является основной целью конструкторов – реализовать код для многократного создания однотипных объектов.
Давайте ещё раз отметим – технически любая функция (кроме стрелочных функций, поскольку у них нет this ) может использоваться в качестве конструктора. Его можно запустить с помощью new , и он выполнит выше указанный алгоритм. Подобные функции должны начинаться с заглавной буквы – это общепринятое соглашение, чтобы было ясно, что функция должна вызываться с помощью «new».
new function() < … >
Если в нашем коде присутствует большое количество строк, создающих один сложный объект, то мы можем обернуть их в функцию-конструктор, которая будет немедленно вызвана, вот так:
// создаём функцию и сразу же вызываем её с помощью new let user = new function() < this.name = "John"; this.isAdmin = false; // . другой код для создания пользователя // возможна любая сложная логика и инструкции // локальные переменные и так далее >;
Такой конструктор не может быть вызван снова, так как он нигде не сохраняется, просто создаётся и тут же вызывается. Таким образом, этот трюк направлен на инкапсуляцию кода, который создаёт отдельный объект, без возможности повторного использования в будущем.
Проверка на вызов в режиме конструктора: new.target
Продвинутая возможность
Синтаксис из этого раздела используется крайне редко. Вы можете пропустить его, если не хотите углубляться в детали языка.
Используя специальное свойство new.target внутри функции, мы можем проверить, вызвана ли функция при помощи оператора new или без него.
В случае обычного вызова функции new.target будет undefined . Если же она была вызвана при помощи new , new.target будет равен самой функции.
function User() < alert(new.target); >// без "new": User(); // undefined // с "new": new User(); // function User
Это можно использовать внутри функции, чтобы узнать, была ли она вызвана при помощи new , «в режиме конструктора», или без него, «в обычном режиме».
Также мы можем сделать, чтобы вызовы с new и без него делали одно и то же:
function User(name) < if (!new.target) < // в случае, если вы вызвали меня без оператора new return new User(name); // . я добавлю new за вас >this.name = name; > let john = User("John"); // переадресовывает вызов на new User alert(john.name); // John
Такой подход иногда используется в библиотеках, чтобы сделать синтаксис более гибким. Чтобы люди могли вызывать функцию с new и без него, и она все ещё могла работать.
Впрочем, вероятно, это не очень хорошая практика использовать этот трюк везде, так как отсутствие new может ввести разработчика в заблуждение. С new мы точно знаем, что создаётся новый объект.
Возврат значения из конструктора, return
Обычно конструкторы не имеют оператора return . Их задача – записать все необходимое в this , и это автоматически становится результатом.
Но если return всё же есть, то применяется простое правило:
- При вызове return с объектом, вместо this вернётся объект.
- При вызове return с примитивным значением, оно проигнорируется.
Другими словами, return с объектом возвращает этот объект, во всех остальных случаях возвращается this .
К примеру, здесь return замещает this , возвращая объект:
function BigUser() < this.name = "John"; return < name: "Godzilla" >; // alert( new BigUser().name ); // Godzilla, получили этот объект
А вот пример с пустым return (или мы могли бы поставить примитив после return , неважно):
function SmallUser() < this.name = "John"; return; // alert( new SmallUser().name ); // John
Обычно у конструкторов отсутствует return . Здесь мы упомянули особое поведение с возвращаемыми объектами в основном для полноты картины.
Пропуск скобок
Кстати, мы можем не ставить круглые скобки после new :
let user = new User; //
Пропуск скобок считается плохой практикой, но просто чтобы вы знали, такой синтаксис разрешён спецификацией.
Создание методов в конструкторе
Использование конструкторов для создания объектов даёт большую гибкость. Функции-конструкторы могут иметь параметры, определяющие, как создавать объект и что в него записывать.
Конечно, мы можем добавить к this не только свойства, но и методы.
Например, new User(name) ниже создаёт объект с заданным name и методом sayHi :
function User(name) < this.name = name; this.sayHi = function() < alert( "Меня зовут: " + this.name ); >; > let john = new User("John"); john.sayHi(); // Меня зовут: John /* john = < name: "John", sayHi: function() < . >> */
Для создания сложных объектов есть и более продвинутый синтаксис – классы, который мы рассмотрим позже.
Итого
- Функции-конструкторы или просто конструкторы, являются обычными функциями, но существует общепринятое соглашение именовать их с заглавной буквы.
- Функции-конструкторы следует вызывать только с помощью new . Такой вызов подразумевает создание пустого this в начале и возврат заполненного в конце.
Мы можем использовать конструкторы для создания множества похожих объектов.
JavaScript предоставляет функции-конструкторы для множества встроенных объектов языка: таких как Date , Set , и других, которые нам ещё предстоит изучить.
Мы ещё вернёмся к объектам!
В этой главе мы рассмотрели только основы объектов и конструкторов. Данная информация необходима нам для дальнейшего изучения типов данных и функций в последующих главах.
Как только мы с ними разберёмся, мы вернёмся к объектам для более детального изучения в главах Прототипы, наследование и Классы.
Объекты. Создание и сохранение объектов классов. Оператор new . Области сохранения данных в памяти. Использование массивов ссылок на объекты
В Java для работы с объектами используется единый синтаксис. Объект класса объявляется с помощью ссылки (reference).
Общая форма объявления объекта класса без выделения памяти для него имеет следующий вид:
ClassName objName;
- ClassName – имя класса для которого создается объект с именем objName;
- objName – имя ссылки на объект класса ClassName .
Вышеприведенное объявление говорит о том, что идентификатор objName есть ссылкой на объект класса ClassName . Для ссылки нужно выделить память (инициализировать ссылку) с помощью оператора new как показано ниже:
objName = new ClassName();
Если не выделить память для ссылки и обратиться к нему как к объекту класса, то возникнет ошибка.
Существует и другая общая форма объявления объекта класса. В этом случае память выделяется при его объявлении:
ClassName objName = new ClassName();
Выделение памяти для ссылки на объект класса еще называется «присоединение» объекта к ссылке.
2. Примеры создания объектов разных классов
Пример 1. Создание объекта класса CLine , реализующего линию на координатной плоскости. Программный код объявления класса следующий:
// класс, который реализует линию на координатной плоскости public class CLine < // внутренние переменные класса private double x1, y1, x2, y2; // конструкторы класса // конструктор без параметров CLine() < x1 = y1 = 0; x2 = y2 = 1; > // конструктор с 4 параметрами CLine(double x1, double y1, double x2, double y2) < this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; > // методы доступа // чтение данных public double GetX1() < return x1; > public double GetY1() < return y1; > public double GetX2() < return x2; > public double GetY2() < return y2; > // запись данных void SetXY(double nx1, double ny1, double nx2, double ny2) < x1 = nx1; y1 = ny1; x2 = nx2; y2 = ny2; > // метод, который вычисляет длину линии double Length() < double len; len = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); return len; > >
Нижеследующий программный код демонстрирует создание и использование объектов класса CLine .
public class CTestLine < public static void main(String[] args) < double x, y; // дополнительные переменные // создание объекта класса CLine с помощью конструктора без параметров CLine line1 = new CLine(); // создание объекта класса CLine с помощью конструктора с 4 параметрами CLine line2 = new CLine(2.0, 3.0, 4.0, 5.0); // использование объектов класса line1 x = line1.GetX1(); // x = 0.0 y = line1.GetY2(); // y = 1.0 // использование объекта класса line2 x = line2.GetX1(); // x = 2.0 x = line2.GetX2(); // x = 4.0 y = line2.GetY2(); // y = 5.0 // переопределение объекта line1, предшествующий объект будет уничтожен при "сборке" мусора line1 = new CLine(-4.0, -2.0, 33.4, -20.5); x = line1.GetX1(); // x = -4.0 y = line1.GetY2(); // y = -20.5 > >
Как видно из кода, в функции main() объявляются две ссылки с именами line1 , line2 на объекты класса CLine . Для этих ссылок выделяется память с помощью оператора new. Затем, для объекта line2 память снова переопределяется. Старая память будет освобождена при очередной «сборке» мусора.
Пример 2. Создание объекта класса CName , который реализует имя. Функция main() демонстрирует создание объекта класса CName разными способами с помощью разных конструкторов.
// класс, который реализует имя public class CName < private String name; private String surname; private String patronymic; // конструкторы класса // конструктор без параметров CName() < name = surname = patronymic = ""; > // конструктор с тремя параметрами CName(String _name, String _surname, String _patronymic) < name = _name; surname = _surname; patronymic = _patronymic; > // методы доступа String GetName() < return name; > String GetSurname() < return surname; > String GetPatronymic() < return patronymic; > // функция, которая демонстрирует применение класса CName public static void main(String[] args) < CName nm1 = new CName(); // вызывается конструктор без параметров CName nm2; // просто объявление ссылки на объект класса CName, память еще не выделена nm2 = new CName("Happy", "New", "Year!"); // создание объекта - выделение памяти // проверка String str; str = nm1.GetName(); // str = "" str = nm1.GetSurname(); // str = "" str = nm2.GetName(); // str = "Happy" str = nm2.GetSurname(); // str = "New" str = nm2.GetPatronymic(); // str = "Year!" > >
3. Какие существуют области хранения данных в программах на Java?
В Java для хранения данных (объектов) существует 5 разных хранилищ:
- регистры. В этом случае данные сохраняются внутри процессора. В регистрах данные обрабатываются быстрее всего. Однако, количество регистров есть строго ограниченным. Компилятор использует регистры по мере необходимости. В Java нет непосредственных команд, чтобы сохранять все данные только в регистрах. Даже в мощных языках C/C++ команды-указания для размещения данных в регистрах носят только рекомендуемый характер;
- стек. Для программы стек размещается в общей оперативной памяти (RAM). Стек организовывается с использованием указателей стека. Стек работает по принципу LIFO (Last-In-First-Out) – последний пришел, первый вышел. Такая организация есть удобной, когда нужно выделять память для локальных функций (методов) разных уровней вложений. В стеке размещаются только указатели на объекты. Сами объекты размещаются в «куче» (heap). Указатель стека сдвигается вниз, если нужно выделить память, и вверх, если память освобождается. Таким образом, по быстродействию, стек уступает только регистрам. Однако, стек не владеет такой гибкостью как «куча», так как компилятору необходимо знать жизненный цикл данных, размещенных в стеке;
- «куча». Это есть хранилище общего назначения которое размещается в оперативной памяти (RAM). Здесь сохраняются все объекты (экземпляры объектов) Java. «Куча» есть более гибкой сравнительно со стеком. Это объясняется тем, что компилятор не тратит дополнительных усилий на определение продолжительности существования объектов, которые находятся в «куче». В программе создание объекта происходит с использованием оператора new. В результате выделяется память из «кучи». Однако, выделение памяти памяти из «кучи» занимает больше времени чем в стеке. Следует отметить, что мощные языки C/C++ поддерживают явное создание объектов как в стеке, так и в «куче»;
- постоянное хранилище. В программах часто используются данные, которые являются неизменными. К таким данным относятся константы (например, строковые константы). Эти данные целесообразно встраивать прямо в код программы. Иногда константы размещаются в постоянной статической памяти (ROM);
- внешнее хранилище. Внешним хранилищем могут быть постоянные (persistent) носители информации, например, жесткий диск компьютера или носители информации отдаленных компьютеров сети. Этот вид сохранения данных позволяет сохранять объекты на носителях информации, а потом восстанавливать их для сохранения в оперативной памяти.
4. В какой области памяти сохраняются объекты и ссылки на объекты?
Объекты сохраняются в «куче» (heap). Ссылки на объекты сохраняются в стеке.
5. Как в Java создаются и сохраняются массивы объектов?
В отличие от C/C++ массив в Java обязательно инициализируется. Доступ за пределами массива невозможен.
Чтобы создать массив объектов нужно использовать запись наподобие:
ClassName arrayObj[];
ClassName[] arrayObj;
- ClassName – имя некоторого класса, который служит типом для массива объектов arrayObj ;
- arrayObj – имя массива объектов.
В вышеприведенном описании объявляется массив ссылок arrayObj на объекты класса ClassName .
Чтобы выделить память для массива arrayObj из 10 элементов типа ClassName , нужно написать:
arrayObj = new ClassName[10];
Это можно сделать другим способом, сразу при объявлении массива:
ClassName arrayObj = new ClassName[10];
Память выделяется только для массива ссылок. Для объектов память еще не выделена. Чтобы выделить память для любого объекта нужно использовать приблизительно следующий код:
for (int i=0; inew ClassName(); >
В вышеприведенном примере выделяется память для любого объекта в массиве объектов arrayObj . Для определения длины массива используется свойство length , которое есть общедоступным для всех видов массивов в Java.
6. Пример объявления и инициализации массива объектов
Пусть задан класс CLine , реализация которого описывается в п. 2. Пример демонстрирует использование массива из n объектов типа CLine . Значение n задается программно ( n = 10).
public class CTestLine < public static void main(String[] args) < int n = 10; CLine[] arrayLines = new CLine[n]; // выделение памяти для массива ссылок // выделение памяти для каждого элемента массива for (int i=0; i // выделение памяти и инициализация каждого отдельного элемента массива arrayLines[i] = new CLine(i*2, i*1.5, i+2.2, i-1); > // использование массива, вычисление суммарной длины всех отрезков double sumLength = 0; for (int i=0; i"Sum color: #008000;">// Sum = 45.45345204172149 > >
Связанные темы
- Применение классов в программах на Java. Определение класса и объекта класса. Примеры
- Область действия объектов (scope). Удаление объектов. Преимущества использования подхода «уборки мусора» (garbage collection) для объектов
Оператор new
Оператор (операторная функция) new создаёт экземпляр объекта, встроенного или определённого пользователем, имеющего конструктор.
Синтаксис
new constructor[([arguments])]
Параметры
Функция, задающая тип объекта.
Список параметров, с которыми будет вызван конструктор.
Описание
Создание объекта, определённого пользователем, требует два шага:
- Написать функцию, которая задаст тип объекта.
- Создать экземпляр объекта, используя new .
Чтобы определить новый тип объекта, создайте функцию, которая задаст его и имя и свойства. Свойство объекта также может быть объектом. Примеры приведены ниже.
Когда исполняется new Foo(. ) , происходит следующее:
- Создаётся новый объект, наследующий Foo.prototype.
- Вызывается конструктор — функция Foo с указанными аргументами и this , привязанным к только что созданному объекту. new Foo эквивалентно new Foo() , то есть если аргументы не указаны, Foo вызывается без аргументов.
- Результатом выражения new становится объект, возвращённый конструктором. Если конструктор не возвращает объект явно, используется объект из п. 1. (Обычно конструкторы не возвращают значение, но они могут делать это, если нужно переопределить обычный процесс создания объектов.)
Всегда можно добавить свойство к уже созданному объекту. Например, car1.color = "black" добавляет свойство color к объекту car1 , и присваивает ему значение " black ". Это не затрагивает другие объекты. Чтобы добавить свойство ко всем объектам типа, нужно добавлять его в определение типа Car.
Добавить свойство к ранее определённому типу можно используя свойство Function.prototype (en-US) . Это определит свойство для всех объектов, созданных этой функцией, а не только у какого-либо экземпляра. Следующий пример добавляет свойство color со значением null всем объектам типа car , а потом меняет его на " black " только у экземпляра car1 . Больше информации в статье prototype (en-US) .
function Car() > car1 = new Car(); console.log(car1.color); // undefined Car.prototype.color = null; console.log(car1.color); // null car1.color = "black"; console.log(car1.color); // black
Примеры
Тип объекта и экземпляры объекта
Предположим, нам нужен тип объекта для автомобилей. Этот тип должен называться car , и иметь свойства: марка, модель и год.
function Car(make, model, year) this.make = make; this.model = model; this.year = year; >
Теперь можно создать экземпляр типа car:
var mycar = new Car("Eagle", "Talon TSi", 1993);
Это выражение создаёт экземпляр mycar и присваивает его свойствам указанные значения. Таким образом, mycar.make принимает значение "Eagle", mycar.year принимает значение 1993, и так далее.
Можно создать любое количество экземпляров car с помощью оператора new . Например:
var kenscar = new Car("Nissan", "300ZX", 1992);
Объект в качестве свойства
Предположим, есть объект person :
function Person(name, age, sex) this.name = name; this.age = age; this.sex = sex; >
Создадим два экземпляра:
var rand = new Person("Rand McNally", 33, "M"); var ken = new Person("Ken Jones", 39, "M");
Изменим определение car , добавив свойство, указывающее владельца — owner :
function Car(make, model, year, owner) this.make = make; this.model = model; this.year = year; this.owner = owner; >
Создадим экземпляры car:
var car1 = new Car("Eagle", "Talon TSi", 1993, rand); var car2 = new Car("Nissan", "300ZX", 1992, ken);
Вместо строковых или численных значений можно передать объект как параметр. Чтобы узнать имя владельца car2 , получим доступ к свойству:
.owner.name;
Спецификации
| Specification |
|---|
| ECMAScript Language Specification # sec-new-operator |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
- Function
- Reflect.construct()
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
MDN
Support
- Product help
- Report an issue
Our communities
Developers
- Web Technologies
- Learn Web Development
- MDN Plus
- Hacks Blog
- Website Privacy Notice
- Cookies
- Legal
- Community Participation Guidelines
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.