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

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

  • что это?
  • какие проблемы он решает?
  • когда это уместно, а когда нет?

14 ответов


он делает 5 вещей:

  1. он создает новый объект. Тип этого объекта просто объект.
  2. он устанавливает этот новый объект внутренний, недоступный,[[прототип]] (т. е. _ _ proto__) свойство быть внешней, доступной функцией конструктора,прототип object (каждый объект функции автоматически имеет прототип свойства).
  3. это делает this переменная указывает на вновь созданный объект.
  4. он выполняет функцию конструктора, используя вновь созданный объект всякий раз, когда - это.
  5. он возвращает вновь созданный объект, если функция-конструктор возвращаетnull ссылка на объект. В этом случае возвращается ссылка на объект.

Примечание: функции-конструктора ссылается на функцию после new ключевое слово, как в

new ConstructorFunction(arg1, arg2)

как только это будет сделано, если запрашивается неопределенное свойство нового объекта, скрипт проверит объект [[прототип]] объект для свойства вместо этого. Вот как вы можете получить что-то похожее на традиционное наследование классов в JavaScript.

самая трудная часть об этом-пункт 2. Каждый объект (включая функции) имеет это внутреннее свойство, называемое [[прототип]]. Может!--12-->только быть установлен во время создания объекта, либо с новая С


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

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

если вы называете это автономной функцией, например:

Foo();

выполнение этой функции добавит два свойства к , называй это, как это с new:

var bar = new Foo();

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


В дополнение к ответу Даниэля Говарда, вот что new делает (или по крайней мере кажется):

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}

пока

var obj = New(A, 1, 2);

эквивалентно

var obj = new A(1, 2);

для начинающих, чтобы понять его лучше

попробуйте следующий код в консоли браузера.

function Foo() { 
    return this; 
}

var a = Foo();       //returns window object
var b = new Foo();   //returns empty object of foo

a instanceof Window;  // true
a instanceof Foo;     // false

b instanceof Window;  // false
b instanceof Foo;     // true

Теперь вы можете прочитать ответ сообщества wiki:)


так что это, вероятно, не для создания экземпляры объекта

Он используется именно для этого. Вы определяете конструктор функций следующим образом:

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

var john = new Person('John');

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

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

все объекты, созданные из этого конструктора теперь будет getName из-за прототипа цепи, к которой у них есть доступ.


JavaScript is объектно-ориентированный язык программирования, и используется именно для создания экземпляров. Он основан на прототипе, а не на классе, но это не означает, что он не объектно-ориентирован.


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

классы не нужны для объектов-Javascript-это прототипа язык.


иногда код проще, чем слова:

var func1 = function (x) { this.x = x; }                    // used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; }   // used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;

A1 = new func1(1);      // has A1.x  AND  A1.y
A2 =     func1(1);      // undefined ('this' refers to 'window')
B1 = new func2(2);      // has B1.x  ONLY
B2 =     func2(2);      // has B2.x  ONLY

для меня, пока я не прототип, я использую стиль func2, поскольку он дает мне немного больше гибкости внутри и вне функции.


на new ключевое слово для создания новых экземпляров объекта. И да, JavaScript-это динамический язык программирования, который поддерживает объектно-ориентированную парадигму программирования. Соглашение об именовании объекта-всегда использовать заглавную букву для объектов, которые должны быть созданы с помощью ключевого слова new.

obj = new Element();

есть уже некоторые очень большие ответы, но я публикую новый, чтобы подчеркнуть мое наблюдение на случай III ниже о том, что происходит, когда у вас есть явный оператор return в функции которого newing up. Посмотрите на случаи ниже:

Дело I:

var Foo = function(){
  this.A = 1; 
  this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1

выше приведен простой случай вызова анонимной функции, на которую указывает Foo. Когда вы вызываете эту функцию, она возвращает undefined. Так как нет явный оператор return, поэтому интерпретатор JavaScript принудительно вставляет return undefined; оператор в конце функции. Здесь окно является объектом вызова (contextual this), который получает новый A и B свойства.

дело II:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1

здесь интерпретатор JavaScript видит new ключевое слово создает новый объект, который действует как объект вызова (contextual this) анонимной функции, на которую указывает Foo. В этом деле A и B стать свойствами вновь созданного объекта (вместо объекта window). Поскольку у вас нет явного оператора return, интерпретатор JavaScript принудительно вставляет оператор return для возврата нового объекта, созданного из-за использования new ключевое слово.

дело III:

var Foo = function(){
  this.A = 1;
  this.B = 2;
  return {C:20,D:30}; 
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.

здесь снова интерпретатор JavaScript видит new ключевое слово создает новый объект, который действует как объект вызова (contextual this) из анонимная функция, указанная Foo. Опять,A и B стать свойствами вновь созданного объекта. Но на этот раз у вас есть явный оператор return, поэтому интерпретатор JavaScript будет не сделать что-нибудь свое.

вещь, чтобы отметить в случае III объект создается из-за new ключевое слово потерялось с Вашего радара. bar фактически указывает на совершенно другой объект, который не является тем, который JavaScript переводчик создан из-за new ключевое слово.


Ну JavaScript на si может сильно отличаться от платформы к платформе, поскольку это всегда реализация исходной спецификации EcmaScript.

в любом случае, независимо от реализации, все реализации JavaScript, которые следуют спецификации EcmaScript, дадут вам объектно-ориентированный язык. Согласно стандарту ES:

ECMAScript-объектно-ориентированный язык программирования для выполнение вычислений и манипулирование вычислительными объектами в среде хоста.

Итак, теперь, когда мы согласились, что JavaScript является реализацией EcmaScript и, следовательно, является объектно-ориентированным языком. Определение new операция на любом объектно-ориентированном языке говорит, что такое ключевое слово используется для создания экземпляра объекта из класса определенного типа (включая анонимные типы, в таких случаях, как C#).

в EcmaScript мы не используем классы, как вы можете Читайте из спецификации:

ECMAScript не использует классы, такие как в C++, Smalltalk или Java. Вместо этого объекты могут создаваться различными способами, в том числе через литеральная нотация или конструкторы via, которые создают объекты, а затем выполняют код, инициализирующий все или часть из них, назначая initial значения их свойств. Каждый конструктор-это функция, которая имеет свойство ― прототип ‖, используемый для реализации наследования на основе прототипа и общие свойства. Объекты создаются
использование конструкторов в новых выражениях; например, new Дата(2009,11) создает новый объект Date. Вызов конструктора без использования new имеет последствия, которые зависят от конструктора. Например, Date () создает строковое представление текущая дата и время, а не объект.


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

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


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

var Foo = function() {};
Foo.prototype.bar = 'bar';

var foo = new Foo();
foo instanceof Foo; // true

экземпляры наследуются от prototype функции-конструктора. Так приведен пример выше...

foo.bar; // 'bar'

резюме:

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

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

пример:

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

const doggie = new Dog(12);

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

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

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