new、对象类型和Class
new
在JavaScript中,new 是一个操作符,用于创建
一个用户定义的对象类型的实例
或者具有构造函数的内置对象类型的实例
。
当你使用 new 操作符后跟一个构造函数时,JavaScript 会进行以下步骤:
- 创建一个全新的空对象。
- 将这个新对象的原型设置为构造函数的 prototype 属性。
- 将构造函数的 this 关键字指向这个新对象,以便可以访问这个新对象的上下文。
- 执行构造函数内的代码(该代码通常用于初始化新对象的属性)。
- 如果构造函数返回一个对象,则返回该对象;否则,返回步骤1创建的新对象。
例如,假设你有一个简单的构造函数 Person:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
};
现在,你可以使用 new 操作符来创建一个 Person 实例:
var person1 = new Person('Alice', 30);
person1.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.
当 new Person(‘Alice’, 30) 被执行时,会发生以下事情:
- 创建一个新对象 {}。
- 设置新对象的原型为 Person.prototype。
- 在新对象的上下文中调用 Person 构造函数,此时 this 指向这个新对象,即 this.name 和 this.age 被赋值为 ‘Alice’ 和 30。
- 返回这个新对象,因为构造函数没有返回任何其他对象。
因此,通过 new 创建的对象继承自构造函数的原型链,这意味着可以访问那些定义在原型上的属性和方法。这是 JavaScript 中原型继承和面向对象编程概念的一部分。
需要注意的是,如果你忘记使用 new 调用构造函数,this 将指向全局对象(在浏览器中是 window),这可能导致不可预期的结果,并且很可能污染全局命名空间。
从ES6开始,class 关键字被引入了JavaScript中
,它提供了一种更清晰和更面向对象的方式来创建对象和实现继承。但在底层,class 也只是语法糖,JavaScript 的类同样使用 new 操作符来创建实例。
对象类型和class
在JavaScript中,“对象类型”通常指的是通过函数(构造函数)或者class关键字定义的可以用来创建对象的模板。
最初,JavaScript中没有类(class)的概念,所有东西都是以对象的形式存在的。
为了实现类似其他语言中类的功能,JavaScript使用了构造函数加上原型继承的方式。
构造函数
构造函数是一种特殊的函数,它们的命名通常以大写字母开头(按照惯例),并且当你想要创建一个新的对象实例时,你会使用new操作符调用它们。例如:
function Car(make, model) {
this.make = make;
this.model = model;
}
Car.prototype.honk = function() {
console.log('Beep beep!');
};
const myCar = new Car('Toyota', 'Corolla');
myCar.honk(); // Beep beep!
在这里,Car是一个对象类型,它定义了一种车辆,并且每个通过new Car()创建的实例都会继承honk方法。
Class关键字
ES6引入了class关键字,使得面向对象编程在语法上更接近于其他语言如Java、C#等。class提供了一种声明清晰和更正式的方式来创建对象类型。其背后仍然使用原型链作为基础。
class Car {
constructor(make, model) {
this.make = make;
this.model = model;
}
honk() {
console.log('Beep beep!');
}
}
const myCar = new Car('Toyota', 'Corolla');
myCar.honk(); // Beep beep!
在这个例子中,Car类的行为几乎和之前通过构造函数定义的Car一样,但是语法更简洁,更易于理解。
对象类型和Class的区别
虽然从表面上看,使用构造函数和使用class创建的对象类型有相似的行为,但是还是有一些关键的差异:
- 语法差异:class语法更加简洁、直观。
- 严格模式:在类的上下文中,代码自动运行在严格模式下(“use strict”;)。
- 构造函数:类的构造器内不使用显式的prototype定义方法,而是使用更简洁的语法;此外,类构造器不能像普通函数那样被调用——如果没有new操作符,它们会抛出一个错误。
- 继承:类使得继承变得更容易,extends关键字提供了一种声明式的继承方式,比起构造函数原型链手动绑定更加方便。
- 方法定义:类中定义的方法是不可枚举的,而通过构造函数prototype添加的方法是可枚举的。
- 静态方法:class允许定义静态方法,这些方法不会被类的实例继承,而是直接通过类来调用。
尽管class在语法上更接近传统的OOP语法,但它在JavaScript中更多的是语法糖,底层仍然是基于原型链的继承。这意味着即使在使用class关键字的情况下,JavaScript仍然是一种基于原型的编程语言。