Что возвращается от конструктора?

Если я верну какое-то значение или объект в функции конструктора, что получит var?

function MyConstroctor()
{
    //what in case when return 5;
    //what in case when return someObject;
}

var n = new MyConstroctor();

что n получит в обоих случаях?

Собственно, это вопрос викторины, каков будет ответ?
Что возвращается из конструктора пользовательских объектов?
a) Недавно созданный объект
b) undefined - конструкторы не возвращают значения
c) Каково бы ни было утверждение возврата d) Какое бы ни было выражение о возврате; вновь созданный объект, если оператор возврата

Ответ 1

Я нашел эту замечательную ссылку:

JavaScript: возвращаемое значение конструктора

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

var g_deebee = new Deebee();
function Deebee() { return g_deebee; }
var db1 = new Deebee();
var db2 = new Deebee();
if (db1 != db2)
  throw Error("JS constructor returned wrong object!");

Ответ 2

Краткий ответ

Конструктор возвращает объект this.

function Car(){
   this.num_wheels = 4;
}

// car = {num_wheels:4};
var car = new Car();

Длинный ответ

В спецификации Javascript, когда функция вызывается с помощью new, Javascript создает новый объект, затем устанавливает свойство "constructor" этого объекта вызываемой функции и, наконец, присваивает этому объекту имя this, Затем у вас есть доступ к объекту this для тела функции.

Как только тело функции будет выполнено, Javascript вернется:

Любой объект, если функция вручную возвращает один:

function Car(){
  this.num_wheels = 4;
  return {num_wheels:37};
}

var car = new Car();
alert(car.num_wheels); // 37!

Объект this, если функция не имеет оператора return ИЛИ если функция возвращает значение типа, отличного от object

function Car() {
  this.num_wheels = 4;
  return 'VROOM';
}

var car = new Car();
alert(car.num_wheels) // 4
alert(Car()); // No 'new', so this alerts 'VROOM'

Ответ 3

В основном, если ваш конструктор возвращает примитивное значение, такое как строка, число, логическое, нулевое или неопределенное (или вы не возвращаете ничего, что эквивалентно возвращению undefined), вновь созданный объект, который наследуется от prototype конструктора, будет вернулся.

Что объект, к которому у вас есть доступ, с помощью ключевого слова this внутри конструктора при вызове с new ключевым словом.

Например:

function Test() {
  return 5; // returning a primitive
}

var obj = new Test();
obj == 5; // false
obj instanceof Test; // true, it inherits from Test.prototype
Test.prototype.isPrototypeOf(obj); // true

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

function Test2() {
  this.foo = ""; // the object referred by 'this' will be lost...
  return {foo: 'bar'};
}

var obj = new Test2();
obj.foo; // "bar"

Если вас интересуют внутренности new оператора, вы можете проверить алгоритм внутренней операции [[Construct]], который отвечает за создание нового объекта, наследуемого от прототипа конструктора, и чтобы решить, что возвращать:

13.2.2 [[Construct]]

Когда внутренний метод [[Construct]] для объекта Function F вызывается с возможно пустым списком аргументов, предпринимаются следующие шаги:

  1. Пусть obj будет вновь созданным нативным объектом ECMAScript.
  2. Установите все внутренние методы obj как указано в 8.12.
  3. Установите для внутреннего свойства [[Class]] объекта obj значение "Object".
  4. Установите для внутреннего свойства [[Extensible]] объекта obj значение true.
  5. Пусть proto будет значением вызова внутреннего свойства [[Get]] для F с аргументом "prototype".
  6. Если Type(proto) равен Object , set the для внутреннего свойства [[Prototype]] 'объекта obj значение proto.
  7. Если Type(proto) не является Object, установите внутреннее свойство [[Prototype]] объекта obj для стандартного встроенного объекта-прототипа Object, как описано в 15.2.4.
  8. Пусть result будет результатом вызова внутреннего свойства [[Call] ] для F, предоставив obj в качестве значения this и предоставив список аргументов, переданный в [[Construct]] качестве аргументов.
  9. Если Type(result) - Объект, тогда возвращают результат.
  10. Вернуть obj

Ответ 4

Вы не должны возвращать что-либо в конструкторе. Для инициализации объекта используется конструктор. Если вы хотите знать, что произойдет, если вы вернетесь 5, тогда n будет просто пустым объектом, и если вы вернетесь, например, { a: 5 }, то n будет иметь свойство a=5.

Ответ 5

Чтобы ответить на ваш конкретный вопрос:

function MyConstructor()
{
    return 5;
}
var n = new MyConstructor();

n - это экземпляр объекта MyConstructor.

function SomeObject(name) {
    this.name = name;
    this.shout = function() {
        alert("Hello " + this.name)
    }
} 

function MyConstructor()
{
    return new SomeObject("coure06");
}

var n = new MyConstructor();

 n.shout();

n является экземпляром SomeObject (вызов n.shout(), чтобы доказать это)

Чтобы все было абсолютно ясно...

1) Если вы вернете примитивный тип, например число или строку, оно будет проигнорировано. 2) В противном случае вы вернете объект

Функции и конструкторы в JavaScript одинаковы, но как вы их называете, они меняют свое поведение. Быстрый пример этого ниже...

function AddTwoNumbers(first, second) {
    return first + second;
}

var functionCall = AddTwoNumbers(5, 3);
alert(functionCall);// 8

var constructorCall = new AddTwoNumbers(5, 3);
alert(constructorCall);// object

Ответ 6

Это так просто, как сказано в документации (новый оператор):

Объект, возвращаемый функцией-конструктором, становится результатом всего выражения new. Если функция конструктора явно не возвращает объект, вместо этого используется объект, созданный на шаге 1. (Обычно конструкторы не возвращают значения, но они могут сделать это, если они хотят переопределить процесс создания обычного объекта.)

Ответ 7

Вы ничего не можете вернуть из конструктора!

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

  • Имя конструктора - это имя класса. Конструкторы должны иметь то же имя, что и класс.
  • Конструктор по умолчанию. Если вы не определяете конструктор для класса, конструктор без параметров автоматически создается компилятором. Конструктор по умолчанию вызывает родительский конструктор по умолчанию (super()) и инициализирует все переменные экземпляра значением по умолчанию (ноль для числовых типов, null для ссылок на объекты и false для булевых).
  • Конструктор по умолчанию создается только при отсутствии конструкторов. Если вы определяете какой-либо конструктор для своего класса, конструктор по умолчанию не создается автоматически.
  • Различия между методами и конструкторами.
    • В заголовке конструктора (заголовке) нет типа возврата. Значение - это сам объект, поэтому нет необходимости указывать возвращаемое значение.
    • В теле конструктора нет оператора return.
    • Первая строка конструктора должна быть либо вызовом другого конструктора в том же классе (с использованием этого), либо вызовом конструктора суперкласса (с использованием супер). Если первая строка не является ни одной из них, компилятор автоматически вставляет вызов конструктору суперкомпьютера без параметров.

Эти различия в синтаксисе между конструктором и методом иногда трудно увидеть при просмотре источника. Было бы лучше иметь ключевое слово, чтобы четко обозначать конструкторы, как это делают некоторые языки.

  • this (...) - вызывает другой конструктор в том же классе. Часто конструктор с несколькими параметрами вызывает конструктор с большим количеством параметров, предоставляя значения по умолчанию для отсутствующих параметров. Используйте это для вызова других конструкторов в одном классе.
  • супер (...). Используйте super, чтобы вызвать конструктор в родительском классе. Вызов конструктора для суперкласса должен быть первым утверждением в теле конструктора. Если вы удовлетворены конструктором по умолчанию в суперклассе, нет необходимости делать ему вызов, потому что он будет предоставлен автоматически.

Пример явного вызова этого конструктора

public class Point {
    int m_x;
    int m_y;

    //============ Constructor
    public Point(int x, int y) {
        m_x = x;
        m_y = y;
    }

    //============ Parameterless default constructor
    public Point() {
        this(0, 0);  // Calls other constructor.
    }
    . . .
}

super (...) - Конструктор суперкласса (родительский)

Объект имеет поля своего класса плюс все поля его родительского класса, класс grandparent, вплоть до корневого класса Object. Нужно инициализировать все поля, поэтому должны быть вызваны все конструкторы! Компилятор Java автоматически вставляет необходимые вызовы конструктора в процесс цепочки конструкторов, или вы можете сделать это явно.

Компилятор Java вставляет вызов родительскому конструктору (супер), если у вас нет вызова конструктора в качестве первого оператора конструктора. Ниже приведен эквивалент конструктора выше.

// Constructor (same as in above example)
public Point(int x, int y) {
    super();  // Automatically done if you don't call constructor here.
    m_x = x;
    m_y = y;
}