19

Что такое ключевое слово 'new' в JavaScript?

11

Ключевое слово new в JavaScript может вызывать путаницу у тех, кто с ним впервые сталкивается, так как у многих складывается впечатление, что JavaScript не является объектно-ориентированным языком программирования.

  • Что это такое?
  • Какие проблемы оно решает?
  • Когда его уместно использовать, а когда нет?

5 ответ(ов)

4

Предположим, у вас есть такая функция:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};

Если вы вызовете её как обычную функцию, вот так:

Foo();

В результате выполнения этой функции два свойства (A и B) будут добавлены к объекту window. Это происходит потому, что window — это объект, который вызвал функцию в таком контексте, а this в функции указывает на объект, который её вызвал. Это верно для JavaScript.

Теперь вызовем её с помощью new:

var bar = new Foo();

Когда вы добавляете new к вызову функции, создаётся новый объект (просто var bar = new Object()), и this внутри функции указывает на этот новый объект, который вы только что создали, а не на объект, вызвавший функцию. Таким образом, bar теперь является объектом с свойствами A и B. Любая функция может быть конструктором; просто не всегда это имеет смысл.

0

Это используется именно для создания экземпляров объектов. Вы определяете функцию-конструктор следующим образом:

function Person(name) {
    this.name = name;
}

var john = new Person('John');

Однако у ECMAScript есть дополнительное преимущество: вы можете расширять функциональность с помощью свойства .prototype, так что мы можем сделать что-то вроде этого...

Person.prototype.getName = function() { return this.name; }

Все объекты, созданные с помощью этого конструктора, теперь будут иметь метод getName благодаря прототипной цепочке, к которой они имеют доступ.

0

Резюме:

Ключевое слово new используется в JavaScript для создания объекта на основе функции-конструктора. Ключевое слово new должно находиться перед вызовом функции-конструктора и выполняет следующие действия:

  1. Создает новый объект.
  2. Устанавливает прототип этого объекта на свойство прототипа функции-конструктора.
  3. Привязывает ключевое слово this к вновь созданному объекту и выполняет функцию-конструктор.
  4. Возвращает вновь созданный объект.

Пример:

function Dog(age) {
  this.age = age;
}

const doggie = new Dog(12);

console.log(doggie);
console.log(Object.getPrototypeOf(doggie) === Dog.prototype); // true

Что именно происходит:

  1. const doggie говорит: нам нужна память для объявления переменной.
  2. Оператор присваивания = говорит: мы собираемся инициализировать эту переменную выражением, находящимся после =.
  3. Выражение - new Dog(12). Движок JavaScript видит ключевое слово new, создает новый объект и устанавливает его прототип на Dog.prototype.
  4. Функция-конструктор выполняется с привязкой this к новому объекту. На данном этапе значение возраста присваивается вновь созданному объекту doggie.
  5. Вновь созданный объект возвращается и присваивается переменной doggie.
0

Ключевое слово new изменяет контекст, в котором выполняется функция, и возвращает указатель на этот новый контекст.

Когда вы не используете ключевое слово new, контекст, в котором выполняется функция Vehicle(), совпадает с тем контекстом, из которого вы вызываете функцию Vehicle. В этом случае ключевое слово this будет ссылаться на один и тот же контекст. Когда вы используете new Vehicle(), создается новый контекст, и в этом контексте ключевое слово this указывает на только что созданный объект. В результате выполнения вы получаете именно этот новый контекст.

0

В вашем коде есть две функции, func1 и func2, которые демонстрируют разные способы работы с объектами в JavaScript. Давайте разберем предоставленный код по частям:

var func1 = function (x) { this.x = x; }                   // Используется только с 'new'
var func2 = function (x) { var z={}; z.x = x; return z; }  // Можно использовать обоими способами
func1.prototype.y = 11;
func2.prototype.y = 12;

A1 = new func1(1);  // У A1 есть A1.x  И  A1.y
A2 =     func1(1);  // Неопределено (в 'this' ссылается на 'window')
B1 = new func2(2);  // У B1 есть только B1.x
B2 =     func2(2);  // У B2 есть только B2.x

Объяснение кода:

  • func1 предназначена для использования только как конструктор (с использованием new). Она устанавливает значение x как свойство объекта, и из-за добавления свойства y в его прототип, экземпляр A1 будет иметь доступ как к A1.x, так и к A1.y.
  • При вызове func1(1) без new, контекст this ссылается на глобальный объект (обычно window в браузерах), что приводит к отсутствию свойств, определённых в функции.
  • func2 позволяет создавать объекты как с использованием new, так и без. Она возвращает новый объект, который содержит только значение x, но не имеет доступа к y, так как это свойство добавляется к прототипу, а не непосредственно к создаваемому объекту.

Ваш вывод: Вы правы, использование func2 даёт больше гибкости, так как позволяет создавать объекты как конструкторами, так и обычными вызовами функций. Если вам не нужно использовать прототипы, func2 — предпочтительный выбор для простоты и ясности кода.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь