关于 new 操作符

作者: 别过经年 | 来源:发表于2019-05-11 23:59 被阅读0次

1. 为什么要有new操作符?

JS 的 new 到底是干什么的? 本文指出,new 操作符其实就是个语法糖,用了new 可以减少做四件事:

  1. 不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
  2. 不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
  3. 不用 return 临时对象,因为 new 会帮你做;
  4. 不要给原型想名字了,因为 new 指定名字为 prototype。

2. 关于new的面试题

来自lio-mengxiang 的沸点

请问以下表达式输出什么

function Person(name) { 
  this.name = name 
  return 1; 
} 
var p1 = new Person('Tom') 

function Person2(name) { 
  this.name = name 
  return {a:1}; 
} 
var p1 = new Person2('Tom')

答案:第一个输出{name: 'Tom'},第二个输出{a:1}

评论区给了为什么得到的是这个答案,构造函数实例化的规则是,函数return引用类型的话,则new出来的实例对象就是该return引用类型,否则就是构造函数默认的实例对象

关于JavaScript new 的一些疑问?给了更加详细的答案,文中提到的创建数组实例加不加new关键字来自于《JavaScript高级程序设计》的86页,加不加new关键字都是一样的。
但是并不是所有的构造函数都可以不加new去实例化对象,对于Array构造函数来讲,不写new只是个省略写法。直接调用也和使用new调用一样,只是少写个单词而已。但要注意的是,这种表现不适用于自定义的构造函数。并且,即使是JS原生的构造函数,是否通过new关键字调用,可能具有相同的行为,比如Object, Array, RegExp,两种方式都是创建实例;也可能具有不同的行为,比如Date()、Boolean()、Number()、String(),它们使用new关键字调用函数创建的是实例对象(也叫做基本包装类型),而直接调用的结果是强制类型转换(它们与自定义构造函数的表现比较接近)。

3. 模拟new操作符实现

JS 的 new 到底是干什么的? 可以看出new就是个语法糖,抛开这个语法糖,我们自己用原始的方式实现就是了。

JavaScript深入之new的模拟实现

面试官问:能否模拟实现JS的new操作符

看了两个大佬的写法后,过几天,自己手动实现下,实现主要就是绑定this跟原型

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

Person.prototype.say = function() {
  console.info("i am ", this.name);
};

// const p = new Person("geek", 88);

// console.info(p);

// 绑定this 绑定原型

function mockNew(constructor) {
  const args = Array.prototype.slice.call(arguments);
  // 或者用shift
  const params = args.slice(1);

  let instance = {};

  const ret = constructor.apply(instance, params);

  if (ret !== null && typeof ret === "object") {
    return ret; // 如果返回的是对象,返回的对象的原型并没有继承自constructor.prototype
  }

  instance.__proto__ = constructor.prototype;

  return instance;
}

const pp = mockNew(Person, 30, "geek");

console.info(pp);

pp.say();

不传constructor,使用shift拿到constructor

function mockNew() {
  const args = Array.prototype.slice.call(arguments);

  const constructor = args.shift();

  let instance = {};

  const ret = constructor.apply(instance, args);

  if (ret !== null && typeof ret === "object") {
    return ret; // 如果返回的是对象,返回的对象的原型并没有继承自constructor.prototype
  }

  instance.__proto__ = constructor.prototype;

  return instance;
}

再或者用es6展开运算符

function mockNew(constructor, ...args) {
  let instance = {};

  const ret = constructor.apply(instance, args);

  if (ret !== null && typeof ret === "object") {
    return ret; // 如果返回的是对象,返回的对象的原型并没有继承自constructor.prototype
  }

  instance.__proto__ = constructor.prototype;

  return instance;
}

因为__proto__不是标准,所以可以使用Object.create绑定原型

function mockNew(constructor, ...args) {
  let instance = Object.create(constructor.prototype);
  // 这个时候constructor.prototype===instance.__proto__ 成立

  const ret = constructor.apply(instance, args);

  if (ret !== null && typeof ret === "object") {
    return ret; // 如果返回的是对象,返回的对象的原型并没有继承自constructor.prototype
  }

  return instance;
}

再或者使用es6的Object.setPrototypeOf绑定原型

function mockNew(constructor, ...args) {
  let instance = {};
  // 这个时候constructor.prototype===instance.__proto__ 成立
  Object.setPrototypeOf(instance, constructor.prototype);

  const ret = constructor.apply(instance, args);

  if (ret !== null && typeof ret === "object") {
    return ret; // 如果返回的是对象,返回的对象的原型并没有继承自constructor.prototype
  }

  return instance;
}

相关文章

  • 关于 new 操作符

    1. 为什么要有new操作符? JS 的 new 到底是干什么的? 本文指出,new 操作符其实就是个语法糖,用了...

  • 关于new操作符

    一 通过构造函数与class类实现一个简单的创建实例的过程 二 new一个对象时发生了什么 创建一个空对象,将空对...

  • 关键字new

    关于new操作符,我们最常看到的代码像这样: new操作符具体干了什么呢?我们可以用代码模拟它的行为。 创建了一个...

  • JS基础回归01:new操作符,原型和原型链

    本篇介绍 new 操作符的背后原理以及 JS 如何依赖原型形成原型链,完成继承。 new 操作符的本质 new 操...

  • js中的new关键字都干了些什么?

    new 操作符 在有上面的基础概念的介绍之后,在加上new操作符,我们就能完成传统面向对象的class + new...

  • new

    什么是new操作符 new会生成一个实例对象,该对象的this指向该实例 实现一个new操作符

  • 关于 C++ 里的 New

    new expression : new 表达式 operator new : 操作符函数,用来分配内存. ...

  • c++_动态对象创建

    一.c语言 c语言使用malloc 来创建堆对象 二.c++ new操作符 delete操作符 如果new []...

  • new 对象 class

    new 操作符具体干了什么? 当我们new一个数据的时候,new操作符到底做了什么? 首先是创建实例对象{},th...

  • 刘铁猛C#(11)操作符详解(下)

    New 操作符 不仅是个关键字,也是操作符,用于创建实例,是实例构造器的操作符。 1)new 可以创建一个类型的实...

网友评论

    本文标题:关于 new 操作符

    本文链接:https://www.haomeiwen.com/subject/qqkqaqtx.html