new运算符是JavaScript中的重要概念之一,是我们在编程、开发中经常会使用到的。在本文中,我们将从多个方面对new运算符进行详细的讲解,希望能给大家带来更深入的理解。
一、new 运算符的基本原理
new 运算符用于创建一个实例对象,先创建一个空对象,然后调用实例对象的构造函数,将空对象作为this传入,执行构造函数里面的逻辑,同时this指向空对象,返回一个这个空对象的引用,这个引用就是new出来的实例对象。
下面是一个简单的演示,展示new运算符的基本原理:
function Person(name, age) { this.name = name; this.age = age; } let person = new Person('Tom', 18); console.log(person); // Person {name: "Tom", age: 18}
在上面的例子中,我们先定义了一个构造函数 Person,然后用new运算符创建一个实例对象 person。执行 new Person(‘Tom’, 18) 时,JavaScript 引擎会先创建一个空对象,然后把这个空对象作为参数调用 Person 函数,并且在执行 Person 函数时将this指向新建的这个空对象,这样就可以给空对象添加属性了,最后将这个对象返回。
二、new 运算符与Object.create()的差别
很多人在理解new运算符的时候会与Object.create()搞混,这里我们来看一下他们的区别。
Object.create()也是用来创建对象的方法,但它与new运算符不同的是,它创建的对象是以指定对象为原型创建的。这个对象的原型链上将会包含指定对象,如果指定对象为null,那么它将创建一个没有原型的对象。
下面是一个简单的演示:
let person1 = Object.create(null); let person2 = new Object(); console.log(person1.__proto__); //undefined console.log(person2.__proto__); //{}
在上面的代码中,我们通过Object.create(null)来创建了一个没有原型的对象,然后通过person1.__proto__可以看到它的值为undefined;而通过new Object()创建的person2对象,它的原型链上包含了一个空对象{}。
三、new 运算符和构造函数
前面我们已经提到new 运算符用于创建一个实例对象,它的实际操作是先创建一个空对象,再调用实例对象的构造函数,将空对象作为this传入,执行构造函数里面的逻辑,同时this指向空对象,返回一个这个空对象的引用。
构造函数是用来创建对象的函数,可以带参数,也可以不带参数。它的内部实现逻辑就是new 运算符的逻辑,只是在“实例对象”的创建部分略有不同。构造函数在被new调用时,系统会自动创建一个空对象并将其传入构造函数,并且在构造函数中使用的this指向这个新创建的空对象。最后,将该对象返回作为new表达式的值,从而完成了“实例对象”的创建。
function Person(name, age) { this.name = name; this.age = age; } let person = new Person("Tom", 18); console.log(person);
在上面的代码中,我们首先定义了一个构造函数,它的作用是给每个实例对象添加一个name和age属性。然后使用new运算符来创建一个实例对象person。
四、new 运算符与继承
在JavaScript中,对象之间的继承可以通过原型实现。通过定义对象的原型,可以让这个对象从原型对象中继承属性和方法。可以先通过new运算符创建一个父类实例对象,再把这个实例对象作为子类的原型。这样一来,子类就可以从父类上继承到属性和方法。
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayInfo = function () { console.log("我叫" + this.name + ",我今年" + this.age + "岁"); } function Student(name, age, grade) { this.name = name; this.age = age; this.grade = grade; } Student.prototype = new Person(); let stu = new Student("Tom", 19, 1); stu.sayInfo(); // 我叫Tom,我今年19岁
在上面的例子中,我们先定义了一个构造函数Person,它有两个属性name和age,并且定义了一个原型上的属性sayInfo。然后我们定义了一个构造函数Student,它继承了Person的属性和方法,又自己有一个属性grade。最后通过new运算符创建了一个Student实例对象stu,调用stu.sayInfo()方法,会打印出:“我叫Tom,我今年19岁”,说明Student实例对象stu继承了Person的sayInfo方法。
五、new 运算符和class语法
在ES6中,通过类与继承的语法糖,我们可以更方便地定义构造函数,并且支持继承。使用class语法糖,可以更加直观地展示出继承关系。
class Person { constructor(name, age) { this.name = name; this.age = age; } sayInfo() { console.log(`我叫${this.name},我今年${this.age}岁`); } } class Student extends Person { constructor(name, age, grade) { super(name, age); this.grade = grade; } } let stu = new Student("Tom", 19, 1); stu.sayInfo(); // 我叫Tom,我今年19岁
在上面的代码中,我们通过class语法糖定义了两个类,分别是Person和Student。Person类有两个属性name和age,和一个方法sayInfo。Student类继承了Person类,并且新增了一个属性grade。最后通过new运算符创建了一个Student实例对象stu,调用stu.sayInfo()方法,会打印出:“我叫Tom,我今年19岁”,说明Student实例对象stu继承了Person的sayInfo方法。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/236758.html