su37josephxia/frontend-interview

Day6 - new 一个构造函数,如果函数返回 `return {}` 、 `return null` , `return 1` , `return true` 会发生什么情况?

su37josephxia opened this issue · 21 comments

结论

只有在构造函数 return 的数据类型是 Object 时才会执行该 return 语句,其余情况均返回该构造函数的一个实例。

回答

return {} 返回空对象,
其余情况返回实例。

如果函数返回 return {} 、 return null , return 1 , return true 会发生什么情况?
return {} 会返回这个return的 {}
return 其余的情况会返回这个构造函数所创建的实例对象。

// mock_new.js
export function mockNew() {
  const obj = {};
  const constructor = Array.prototype.shift.call(arguments);
  obj.__proto__ = constructor.prototype;
  const res = constructor.call(obj, arguments);
  return typeof res !== 'object' || res === null ? obj : res;
}

// __test__/interview/mock_new
import { mockNew } from '../../code/interview/mock_new';
function returnObj() {
  this.type = 'object';
  return {
    return: 'obj',
  };
}
function returnNumber() {
  this.type = 'number';
  return 0;
}
function returnBoolean() {
  this.type = 'boolean';
  return false;
}
function returnSymbol() {
  this.type = 'symbol';
  return Symbol('hello');
}
function returnString() {
  this.type = 'string';
  return 'abc';
}
function returnUndefined() {
  this.type = 'undefined';
  return undefined;
}
function returnNull() {
  this.type = 'null';
  return null;
}
function returnBigInt() {
  this.type = 'BigInt';
  return 999n;
}
describe('test mockNew', () => {
  test('return {}', () => {
    expect(mockNew(returnObj)).toEqual({
      return: 'obj',
    });
  });
  test('return Number', () => {
    expect(mockNew(returnNumber)).toEqual({
      type: 'number',
    });
  });
  test('return Boolean', () => {
    expect(mockNew(returnBoolean)).toEqual({
      type: 'boolean',
    });
  });
  test('return Symbol', () => {
    expect(mockNew(returnSymbol)).toEqual({
      type: 'symbol',
    });
  });
  test('return String', () => {
    expect(mockNew(returnString)).toEqual({
      type: 'string',
    });
  });
  test('return Undefined', () => {
    expect(mockNew(returnUndefined)).toEqual({
      type: 'undefined',
    });
  });
  test('return Null', () => {
    expect(mockNew(returnNull)).toEqual({
      type: 'null',
    });
  });
  test('return BigInt', () => {
    expect(mockNew(returnBigInt)).toEqual({
      type: 'BigInt',
    });
  });
});

我把每种情况都打印了一遍

28975cc056096674b99ef8536ebaa36

总结一下:

如果没有return, 默认值返回实例对象;
如果return基础类型,返回默认值, 如果return引用类型则返回引用类型

new 命令总是返回一个对象,要么是实例对象,要么是 return 语句指定的对象

如果 return 返回的是基础数据类型,不会受到影响

new 命令如果 return 是一个对象,那么则返回该对象。如果不是对象,那么则是该构造函数创建的新对象。

构造函数返回{}new之后也会返回这个{}, 其他情况都会返回实例对象

构造函数内返回分为基础类型和引用类型,如果是引用类型,如{}则会返回{},基础类型如1、true则返回实例对象,null在typeof中被作为对象,但是实际上return null 也返回实例对象

如果函数 return {} 会返回 {}
如果return null , return 1 , return true 都会返回新创建的对象

new 一个构造函数,会返回一个对象,如果构造函数中 return 了一个对象,则 new 之后直接返回该对象,否则则返回新创建的对象

  • 如果函数显式的返回引用类型对象 Object,Function,Array,RegExp,Date ,则返回这个对象
  • 如果函数显式的返回基础类型 string,number,undefined,null,boolean,symbol,则返回函数新建的实例对象

new 一个构造函数,如果这个构造函数体内return的是一个对象,那么就直接返回该对象;
如果函数体内没有return或者return的是非对象,那么返回的就是这个构造函数的实例对象;

如果return引用类型返回return后面的代码;
如果return的是基础数据类型,返回默认的实例对象

new一个构造函数,如果return后面是基础类型,会返回new生成的对象,否则的话他会直接返回函数的返回值

如果构造函数return 的值是引用类型 则返回这个值
否则返回生成的实例对象

new 一个构造函数的时候,如果函数返回对象,数组或者函数,则返回函数的返回值,否则返回新创建的实例。

new 一个构造函数的时候,如果函数返回值是一个不为null的object,或者是一个function,则使用这个返回值,否则返回创建的实例对象

如果没有 return 返回值或者return 返回值为基本数据类型,返回创建的实例对象,
如果 return 返回值为引用数据类型,则返回该引用数据类型返回值。

如果函数返回 {},则返回结果为 {}

function Create1(name='snail'){
  this.name = name;
  return {}
}
const instance1 = new Create1();
console.log('instance1',instance1); // {}

如果函数返回 null,则返回结果为创建的实例对象

function Create2(name='snail'){
  this.name = name;
  return null
}
const instance2 = new Create2();
console.log('instance2',instance2); // { name: 'snail' }

如果函数返回 1,则返回结果为创建的实例对象

function Create3(name='snail'){
  this.name = name;
  return 1
}
const instance3 = new Create3();
console.log('instance3',instance3); // { name: 'snail' }

如果函数返回 true,则返回结果为创建的实例对象

function Create4(name='snail'){
  this.name = name;
  return true
}
const instance4 = new Create4();
console.log('instance4',instance4); // { name: 'snail' }

new 一个构造函数,如果函数返回 return {} 、 return null , return 1 , return true 会发生什么情况?

  • 当return的是基本类型的时候,(undefined, null, string, number, boolean ,Symbol)的时候没有影响还是会返回新的空对象

  • 当return的是 引用类型的时候 ,则会返回 return 的 对象,不再是新的对象

  • 当new一个构造函数,函数return返回的值是 string,number,undefined,null,boolean,symbol基础类型的话,则会返回该构造函数创建的全新实例对象

  • 当 return返回的值是,对象或者数组的话,则会直接返回这个对象或者数组本身

image

这4中情况除了返回对象会返回构造函数的返回值外,其它情况都会返回new内部创建的新对象。

MDN

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

结论

new 操作在函数没有默认返回值的情况下, 返回新创建的实例对象, 同时如果返回数据类型为基础数据类型时也是返回实例对象,
只有在函数返回引用类型的时候才会返回其本身, 但是需要注意的是这个时候原本的this就丢失了!

原因

个人猜测, new 作为JS的一个操作符, 其主要作用是返回构造函数的内置对象的实例, 但为了保证我们可以在需要的时候返回自定义的实例, 实现其他特定的需求, 所以设定当用户有返回自定义的对象时, 则返回自定义的对象, 否则其他情况一律返回构造函数的内置对象实例.(PS: 所有的引用类型本质都是对象)

function Person(name) { this.name = name; return {} // return null // return 1 // return true } var p1 = new Person('jie'); console.log(p1);

new 一个构造函数,如果函数返回 return {},会返回空对象,其余情况返回构造函数的实例对象。
应该是返回对象,就返回对象。返回其他类型,就直接取构造函数的实例对象返回了