Что возвращается от конструктора? - PullRequest
16 голосов
/ 28 июля 2010

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

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

var n = new MyConstroctor();

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

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

Ответы [ 6 ]

59 голосов
/ 28 июля 2010

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

Конструктор возвращает объект 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'
37 голосов
/ 28 июля 2010

В основном, если ваш конструктор возвращает примитивное значение , такое как строка, число, логическое, нулевое или неопределенное значение (или вы не возвращаете ничего, что эквивалентно возвращению undefined), a вновь созданный объект, который наследует от конструктора 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 to proto.
  7. Если Type(proto) не является объектом, установите внутреннее свойство [[Prototype]] объекта obj для стандартного встроенного объекта-прототипа объекта, как описано в 15.2.4.
  8. Пусть result будет результатом вызова внутреннего свойства [[Call]] для F, предоставив obj в качестве значения this и предоставив список аргументов, переданный в [[Construct]] в качестве аргументов.
  9. Если Type(result) - Объект, то вернуть результат.
  10. Возврат obj.
19 голосов
/ 28 июля 2010

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

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!");
0 голосов
/ 26 января 2018

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

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

0 голосов
/ 28 июля 2010

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

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
0 голосов
/ 28 июля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...