Создание объекта и новое ключевое слово в javascript [dубликат]

dd if=/dev/cdrom of=/path/to/imagename.iso bs=2048

Вышеуказанная команда сделает записываемый ISO-образ того, что находится на вашем оптическом диске.

1560
задан 25 July 2015 в 16:42

11 ответов

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

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

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

var john = new Person('John');

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

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

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

33
ответ дан 15 August 2018 в 15:49
  • 1
    конструкторы функций используются как классы, нет ключевого слова class, но вы можете в значительной степени сделать то же самое. – meder omuraliev 30 October 2009 в 01:37
  • 2
    Там kindof является ключевым словом класса - класс зарезервирован для будущего использования – Greg 30 October 2009 в 01:41
  • 3
    Кстати, именно поэтому вы используете .className не .class для установки класса CSS – Greg 30 October 2009 в 01:41
  • 4
    Он должен быть капитализированным человеком по соглашению. – eomeroff 26 June 2013 в 18:56

Для начинающих лучше понять

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

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:)

85
ответ дан 15 August 2018 в 15:49
  • 1
    Хороший ответ. Также - выход из return this; дает тот же результат. – Nelu 3 February 2017 в 01:26
  • 2
    Было бы неплохо указать, почему это происходит. – Florian Leitgeb 23 October 2017 в 17:49

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

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

Если вы вызываете это как отдельную функцию следующим образом:

Foo();

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

Теперь вызовите его следующим образом: new:

var bar = new Foo();

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

359
ответ дан 15 August 2018 в 15:49
  • 1
    Зависит от контекста исполнения. В моем случае (Qt-скриптинг) это всего лишь глобальный объект. – Maxym 21 January 2013 в 19:24
  • 2
    это вызовет больший объем использования памяти? – Jürgen Paul 25 July 2013 в 00:20
  • 3
    , потому что окно - это объект, который вызвал функцию - должен быть: потому что окно - это объект, который содержит функцию . – Dávid Horváth 23 July 2016 в 16:22
  • 4
    @Taurus В веб-браузере функция не-метода будет неявным методом window. Даже в закрытии, даже если аноним. Однако в примере это простой вызов метода в окне: Foo(); = & gt; [default context].Foo(); = & gt; [F4]. В этом выражении window является контекстом (не только вызывающий , что не имеет значения). – Dávid Horváth 11 September 2017 в 14:47
  • 5
    @Taurus. Да, да. Однако в ECMA 6 и 7 все сложнее (см. Лямбда, классы и т. Д.). – Dávid Horváth 11 September 2017 в 15:00

В дополнение к ответу Даниэля Говарда, вот что делает 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);
146
ответ дан 15 August 2018 в 15:49
  • 1
    Я обнаружил, что javascript легче понять, чем английский: v – damphat 20 October 2013 в 15:11
  • 2
    Отличный ответ. У меня есть один крошечный вопрос: как можно func.prototype быть null? Не могли бы вы немного рассказать об этом? – Tom Pažourek 2 April 2014 в 16:12
  • 3
    @tomp вы можете переопределить свойство prototype, просто записав A.prototype = null;. В этом случае new A() приведет к объекту, то есть внутренний прототип указывает на объект Object: jsfiddle.net/Mk42Z – basilikum 28 April 2014 в 23:19
  • 4
    Проверка типа может быть неправильной, потому что объект-хост может создавать нечто иное, чем «объект». или "функция". Чтобы проверить, является ли что-то объектом, я предпочитаю Object(ret) === ret. – Oriol 9 October 2015 в 00:40
  • 5
    @Oriol благодарим вас за комментарий. Это правда, что вы говорите, и любой фактический тест должен быть сделан более надежным способом. Тем не менее, я думаю, что для этого концептуального ответа тест typeof просто упрощает понимание того, что происходит за кулисами. – basilikum 9 October 2015 в 00:53

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

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

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

Экземпляры наследуют от функции prototype функции конструктора. Итак, приведенный выше пример ...

foo.bar; // 'bar'
0
ответ дан 15 August 2018 в 15:49
  • 1
    Новое ключевое слово в основном связывает функцию как конструктор; вам ничего не нужно возвращать. Вы можете просто выполнить: function foo (x) {this.bar = x; } var obj = new foo (10); оповещения (obj.bar); – reko_t 30 October 2009 в 01:40
  • 2
    Вам не нужно возвращать объекты из функции конструктора, если вы специально не хотите, с какой-либо целью. Например, если вы должны возвращать экземпляр конкретного объекта вместо создания нового объекта каждый раз (по какой-либо причине). В вашем примере, однако, это совершенно не нужно. – Chetan Sastry 30 October 2009 в 01:43
  • 3
    Ну, это был пример. Вы можете вернуть объект. В этом сценарии много шаблонов, я предоставил его как «например», следовательно, мои слова «например». – eyelidlessness 30 October 2009 в 01:43

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

26
ответ дан 15 August 2018 в 15:49
  • 1
    Я хотел бы сказать, что JavaScript, похоже, еще более объектно-ориентирован, чем все эти языки на основе классов. В JavaScript все, что вы пишете сразу, становится объектом, но на языках классов вы сначала пишете объявления, и только позже вы создаете конкретные экземпляры (объекты) классов. И прототип JavaScript, по-видимому, смутно напоминает все, что VTABLE для языков на основе классов. – JustAMartin 7 October 2013 в 12:33

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

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

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

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

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

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

1
ответ дан 15 August 2018 в 15:49

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

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

1
ответ дан 15 August 2018 в 15:49

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

III :

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; в конце функции. Здесь окно - это объект вызова (контекстный 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, f11] создает новый объект, который действует как объект вызова (контекстная this) анонимной функции, на которую указывает Foo. В этом случае A и B становятся свойствами только что созданного объекта (вместо объекта window). Поскольку у вас нет явного оператора return, поэтому интерпретатор JavaScript принудительно вставляет оператор return, чтобы вернуть новый объект, созданный из-за использования ключевого слова new.

Случай II :

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

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

2
ответ дан 15 August 2018 в 15:49

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

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, поскольку он дает мне немного большую гибкость внутри и снаружи функции. [ ! d1]

3
ответ дан 15 August 2018 в 15:49
  • 1
    B1 = new func2(2); - Почему у этого не будет B1.y? – sunny_dev 17 November 2015 в 13:37
  • 2
    @sunny_dev Я не эксперт JS, но, вероятно, потому, что func2 возвращает непосредственно значение (объект z) вместо работы / возвращения с внутренними значениями (это) – Eagle 19 December 2016 в 13:05

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

obj = new Element();
13
ответ дан 15 August 2018 в 15:49

Другие вопросы по тегам:

Похожие вопросы: