new
Ключевое слово в JavaScript может быть довольно запутанным , когда он впервые встречается, так как люди склонны думать , что JavaScript не является объектно-ориентированный язык программирования.
- Что это?
- Какие проблемы это решает?
- Когда это уместно, а когда нет?
javascript
new-operator
Алон Губкин
источник
источник
Ответы:
Это делает 5 вещей:
this
точку переменной для вновь созданного объекта.this
упоминается.null
ссылку на не объект. В этом случае вместо этого возвращается ссылка на объект.Примечание: функция конструктора ссылается на функцию после
new
ключевого слова, как вКак только это будет сделано, если запрошено неопределенное свойство нового объекта, сценарий проверит объект объекта [[prototype]] вместо этого свойства. Вот как вы можете получить нечто похожее на традиционное наследование классов в JavaScript.
Самая сложная часть этого - точка № 2. Каждый объект (включая функции) имеет это внутреннее свойство, называемое [[prototype]] . Это может быть установлено только во время создания объекта, либо с новым , с Object.create , либо на основе литерала (функции по умолчанию для Function.prototype, числа для Number.prototype и т. Д.). Его можно прочитать только с помощью Object.getPrototypeOf (someObject) . Там есть нет другого пути , чтобы установить или прочитать это значение.
Функции, в дополнение к скрытому свойству [[prototype]] , также имеют свойство с именем prototype , и именно этим вы можете обращаться и изменять, чтобы предоставлять унаследованные свойства и методы для создаваемых вами объектов.
Вот пример:
Это похоже на наследование классов, потому что теперь все объекты, которые вы используете
new ObjMaker()
, также, по-видимому, унаследовали свойство 'b'.Если вы хотите что-то вроде подкласса, то вы делаете это:
Я прочитал тонну мусора на эту тему, прежде чем наконец нашел эту страницу , где это очень хорошо объясняется с помощью хороших диаграмм.
источник
ObjMaker
определяется как функция, которая возвращает значение?new
существует, так что вам не нужно писать фабричные методы для конструирования / копирования функций / объектов. Это означает: «Скопируйте это, сделав его так же, как его родительский« класс »; делайте это эффективно и правильно; и храните информацию о наследовании, которая доступна только мне, JS, для внутреннего использования». Для этого он изменяет недоступный в противном случае внутреннийprototype
объект нового объекта, чтобы непрозрачно инкапсулировать унаследованные члены, имитируя классические цепочки наследования ОО (которые нельзя изменить во время выполнения). Вы можете смоделировать это безnew
, но наследование будет изменяемым во время выполнения. Хорошо? Плохой? Вам решать.Notice that this pattern is deprecated!
. Каков правильный современный шаблон для установки прототипа класса?Предположим, у вас есть эта функция:
Если вы вызываете это как отдельную функцию, вот так:
Выполнение этой функции добавит два свойства к
window
объекту (A
иB
). Он добавляет его вwindow
потому чтоwindow
это объект, который вызвал функцию, когда вы выполняете ее таким образом, иthis
в функции это объект, который вызвал функцию. По крайней мере в Javascript.Теперь назовите это так
new
:Что происходит, когда вы добавляете
new
к вызову функции то, что новый объект создается (простоvar bar = new Object()
) и чтоthis
внутри функции указывает наObject
только что созданный вами объект, а не на объект, который вызвал функцию. Такbar
что теперь объект со свойствамиA
иB
. Любая функция может быть конструктором, просто она не всегда имеет смысл.источник
window
неявная функция будет методом неявно. Даже в закрытии, даже если анонимус. Однако в примере это простой вызов метода для окна:Foo();
=>[default context].Foo();
=>window.Foo();
. В этом выраженииwindow
есть контекст (не только вызывающий , что не имеет значения).В дополнение к ответу Дэниела Ховарда, вот что
new
делает (или, по крайней мере, кажется, делает):Пока
эквивалентно
источник
func.prototype
чтобы бытьnull
? Не могли бы вы рассказать подробнее об этом?A.prototype = null;
В этом случае выnew A()
получите объект on, то есть внутренний прототип указывает наObject
объект: jsfiddle.net/Mk42ZObject(ret) === ret
.typeof
тест просто облегчает понимание того, что происходит за кулисами.Для начинающих, чтобы понять это лучше
Попробуйте следующий код в консоли браузера.
Теперь вы можете прочитать ответ вики сообщества :)
источник
return this;
опускание дает тот же результат.Это используется именно для этого. Вы определяете конструктор функции так:
Однако дополнительное преимущество, которое имеет ECMAScript, заключается в том, что вы можете расширить его с помощью
.prototype
свойства, чтобы мы могли сделать что-то вроде ...Все объекты, созданные из этого конструктора, теперь будут иметь
getName
цепочку прототипов, к которой они имеют доступ.источник
class
ключевого слова, но вы можете сделать то же самое.JavaScript является объектно-ориентированным языком программирования и используется именно для создания экземпляров. Он основан на прототипах, а не на классах, но это не значит, что он не объектно-ориентирован.
источник
Javascript - это динамический язык программирования, который поддерживает парадигму объектно-ориентированного программирования и использует его для создания новых экземпляров объекта.
Классы не нужны для объектов - Javascript - это язык, основанный на прототипах .
источник
Уже есть несколько очень хороших ответов, но я публикую новый, чтобы подчеркнуть мое наблюдение в случае III ниже о том, что происходит, когда у вас есть явный оператор возврата в функции, которую вы
new
вызываете. Посмотрите на следующие случаи:Случай I :
Выше приведен простой пример вызова анонимной функции, на которую указывает
Foo
. Когда вы вызываете эту функцию, она возвращаетсяundefined
. Поскольку явного оператора возврата нет, интерпретатор JavaScript принудительно вставляетreturn undefined;
оператор в конец функции. Здесь окно является объектом вызова (контекстнымthis
), который получает новыйA
иB
свойство.Случай II :
Здесь интерпретатор JavaScript, увидев
new
ключевое слово, создает новый объект, который действует как объект вызова (контекстныйthis
) анонимной функции, на которую указывает указательFoo
. В этом случаеA
иB
становятся свойства вновь создаваемого объекта (вместо оконного объекта). Поскольку у вас нет явного оператора return, интерпретатор JavaScript принудительно вставляет оператор return, чтобы вернуть новый объект, созданный из-за использованияnew
ключевого слова.Случай III :
Здесь снова интерпретатор JavaScript, увидев
new
ключевое слово, создает новый объект, который действует как объект вызова (контекстуальныйthis
) анонимной функции, на которую указывает указательFoo
. Снова,A
иB
становитесь свойствами вновь созданного объекта. Но на этот раз у вас есть явное выражение return, поэтому интерпретатор JavaScript не будет ничего делать самостоятельно.В случае III следует отметить , что создаваемый объект
new
ключевого слова, был потерян с вашего радара.bar
на самом деле указывает на совершенно другой объект, который не тот, который интерпретатор JavaScript создал из-заnew
ключевого слова.Цитата Дэвида Фланагана из JavaScripit: Полное руководство (6-е издание), гл. 4, страница № 62:
--- Дополнительная информация ---
Функции, используемые во фрагменте кода вышеупомянутых случаев, имеют специальные имена в мире JS, как показано ниже:
Случай I и II - функция конструктора
Случай III - Заводская функция. Фабричные функции не должны использоваться с
new
ключевым словом, которое я сделал, чтобы объяснить концепцию в текущем потоке.Вы можете прочитать о разнице между ними в этой теме.
источник
иногда код легче слов:
для меня, пока я не являюсь прототипом, я использую стиль func2, поскольку он дает мне немного больше гибкости внутри и снаружи функции.
источник
B1 = new func2(2);
<- Почему этого не будетB1.y
?new
Ключевое слово изменяет контекст , в котором функция времени запуска и возвращает указатель на этот контекст.Если вы не используете
new
ключевое слово, контекст, в которомVehicle()
выполняется функция, совпадает с контекстом, из которого вы вызываетеVehicle
функцию.this
Ключевое слово будет ссылаться на тот же контекст. Когда вы используетеnew Vehicle()
, создается новый контекст, поэтому ключевое словоthis
внутри функции ссылается на новый контекст. В ответ вы получаете только что созданный контекст.источник
new
Ключевое слово для создания новых экземпляров объектов. И да, javascript - это динамический язык программирования, который поддерживает парадигму объектно-ориентированного программирования. Соглашение об именовании объектов гласит: всегда используйте заглавную букву для объектов, которые должны быть созданы новым ключевым словом.источник
Резюме:
new
Ключевое слово используется в JavaScript для создания объекта из функции конструктора.new
Ключевое слово должно быть перед вызовом функции конструкторы и будет делать следующие вещи:this
ключевое слово к вновь созданному объекту и выполняет функцию конструктораПример:
Что именно происходит:
const doggie
говорит: нам нужна память для объявления переменной.=
говорит: мы собираемся инициализировать эту переменную с помощью выражения после=
new Dog(12)
. Движок JS видит новое ключевое слово, создает новый объект и устанавливает прототип в Dog.prototypethis
значением, установленным для нового объекта. На этом этапе возраст назначается вновь созданному объекту собачка.источник
new
Ключевые слова создают экземпляры объектов с использованием функции в качестве конструктора. Например:Экземпляры наследуются от
prototype
функции конструктора. Итак, приведенный выше пример ...источник
Ну, JavaScript на Си может сильно отличаться от платформы к платформе, поскольку это всегда реализация оригинальной спецификации EcmaScript.
В любом случае, независимо от реализации, все реализации JavaScript, которые соответствуют спецификации EcmaScript, дадут вам объектно-ориентированный язык. Согласно стандарту ES:
Итак, теперь, когда мы договорились, что JavaScript - это реализация EcmaScript и, следовательно, это объектно-ориентированный язык. Определение
new
операции в любом объектно-ориентированном языке говорит, что такое ключевое слово используется для создания экземпляра объекта из класса определенного типа (включая анонимные типы, в случаях, подобных C #).В EcmaScript мы не используем классы, как вы можете прочитать из спецификации:
источник