JS中new了个啥

241 阅读4分钟

在JS中你可能经常会用到new关键字,但不知道它到底干了什么。在这篇文章中,我们将详细解析 new 操作符在 JavaScript 中的工作原理,并探讨其在面向对象编程中的应用。通过理解 new 操作符的内部机制,我们可以更好地掌握 JavaScript 的对象创建和管理方法。

对象字面量与构造函数

在 JavaScript 中,我们可以使用对象字面量来创建简单的对象:

const obj = {
  name: 'Duck',
  sing: function() {
    console.log('gagaga!');
  }
};

这种方式很简洁,但如果我们需要创建多个具有相同行为但不同属性的对象,对象字面量的方式就显得不够灵活。每个对象都需要重复定义相同的行为(方法),这会带来很大的内存开销。

为了解决这个问题,我们可以使用构造函数和 new 操作符:

function Duck(name) {
  this.name = name;
  this.sing = function() {
    console.log('gagaga!');
  };
}

const duck1 = new Duck('Donald');
const duck2 = new Duck('Daffy');

在这个例子中,Duck 构造函数可以为每个实例创建各自的属性,同时共享相同的方法。

new 操作符的工作过程

当我们使用 new 操作符创建一个新的对象时,实际发生了以下几个步骤:

  1. 创建一个空对象:首先,JS 引擎会创建一个空的对象字面量 {},这个对象将作为最终返回的实例。

  2. 运行构造函数:接着,构造函数以 new 的方式运行。在这个过程中,this 关键字会被绑定到新创建的对象上,意味着构造函数内的 this 指向的是这个新对象。

  3. 添加属性:构造函数的运行过程实际上就是逐渐为新对象添加属性的过程。通过 this 关键字,我们可以在构造函数内部为新对象添加各种属性和方法。

  4. 返回对象:默认情况下,构造函数会返回这个新创建的对象。如果构造函数显式地返回一个非对象类型的值,这个返回值会被忽略,仍然返回新创建的对象。

  5. 设置原型链:新对象的 __proto__ 属性会被设置为构造函数的 prototype 属性。这样,新对象就继承了构造函数原型上的所有属性和方法。

下面我们手搓了一个new,并用自己写的mynew创建了一个实例对象。


function myNew(Fun,...args){
    let obj = {}    
    Fun.apply(obj,args);
    obj.__proto__=Fun.prototype 
    return obj;
}
const duck = myNew(Duck,'Donald');
console.log(duck.name)//输出Donald
duck.singing()//输出gagaga!

原型链与方法共享

为了避免每个实例都创建自己的方法,我们可以将方法定义在构造函数的 prototype 属性上,这样所有实例都可以共享这些方法:

function Duck(name) {
  this.name = name;
}

Duck.prototype.sing = function() {
  console.log('gagaga!');
};

const duck1 = new Duck('Donald');
const duck2 = new Duck('Daffy');

duck1.sing(); // 输出 'gagaga!'
duck2.sing(); // 输出 'gagaga!'

在这个例子中,sing 方法被定义在 Duck.prototype 上,因此所有由 Duck 构造函数创建的实例都可以共享这个方法。通过设置 obj.__proto__Duck.prototype,JS 引擎会在对象的原型链上查找属性和方法,如果实例自身没有找到,就会到原型对象上去查找。

JavaScript 的面向对象编程

JavaScript 的面向对象编程与传统的面向对象编程有些不同。在传统的面向对象编程中,类之间存在明确的继承关系(如 C++、Java 等),而在 JavaScript 中,我们使用构造函数和原型来实现对象的行为共享和继承。

通过构造函数,我们可以创建具有各自属性的对象实例,并通过原型链实现方法的共享。这种方式不仅提高了代码的复用性,还降低了内存开销,因为方法只需要在内存中存储一次。但在ES6,JS也引入了class语法糖,提高了代码的结构性和效率。

结语

本文我们详细解析了 JavaScript 中 new 操作符的工作过程,并探讨了其在面向对象编程中的应用。通过理解 new 操作符的内部机制和原型链的工作原理,我们可以更好地设计和优化我们的代码,提升应用程序的性能和可维护性。希望这篇文章能帮助你更好地掌握 JavaScript 的面向对象编程。