Comportamento estranho de Javascript `new` de` function` [duplicado]

Oct 15 2020

Acabei de encontrar algo que realmente me surpreendeu. Considere as quatro funções a seguir:

function A() {
 this.q = 1;
}

function B() {
 this.q = 1;
 return this;
}

function C() {
 this.q = 1;
 return 42;
}

function D() {
 this.q = 1;
 return {};
}

e vamos criar objetos (via new) de todos eles:

console.log('a', new A());
console.log('b', new B());
console.log('c', new C());
console.log('d', new D());

Esta é a saída:

a A { q: 1 }
b B { q: 1 }
c C { q: 1 }
d {}

Os três primeiros parecem indicar que não importa o que a função retorna, que JS só se preocupa com o que cada função faz com this(que era minha crença anterior, aliás). Mas o último contradiz isso.

Então, o que está acontecendo aqui? Minha regra revisada seria "se a função retornar um Object, mantemos isso. Caso contrário, mantemos this". Mas não tenho certeza sobre isso.

Respostas

1 Lorand Oct 16 2020 at 02:51

Quando você usa o novo operador, ele cria um objeto.

O valor de retorno é o esperado. Se no retorno for um objeto, esse objeto será retornado, caso contrário, se no retorno for uma função, essa função será retornada.

function A(){
    this.b = 3;
    return function(){return 4;};
}
function B(){
    this.b = 3;
    return { d:4};
}

console.log(typeof (new A())); //function
console.log(typeof (new B())); //object {d:4}

Caso algum outro valor ou não exista no retorno, este operador terá precedência retornado como objeto.

function C(){
    this.b = 3;
    return "78";
}
console.log(typeof (new C())); // object {b:3}
3 Harkal Oct 16 2020 at 02:40

em JavaScript, quando você invoca uma função sem novidades, como test()se apenas executasse a função e ela. retorna tudo o que está sendo retornado pela função

enquanto, quando você invoca uma função com new like, new test()ela espera que a instrução return retorne um objeto else return thisobject.

então

function test() {
    this.q = 1
}

test(); // return undefined

new test(); // return {q:1}