JavaScript prototype如何工作
在JavaScript中,当给对象添加行为时,如果使用构造函数创建多个对象(使用”new”关键字调用构造函数),那么”new”关键字会将函数调用转换为构造函数调用,并且每次都会创建一个全新的空对象,这会导致不一致性,因为每个对象都会创建一个独立的函数副本,所以如果创建1000个对象,就会创建1000个函数副本,造成内存浪费。
出于这个原因,就引入了原型(prototype)。
原型: 原型是在多个对象之间共享行为和数据的简单方法。原型是Object构造函数的属性。
语法:
Object.prototype
所有在 JavaScript 中创建的对象都是“Object”的实例。因此,它们都共享“Object.prototype”方法。我们还可以覆盖这些属性。
为什么需要原型?
有时需要向给定类型的所有现有对象添加新属性(或方法)。只有将新方法添加到原型函数中才可能实现这一点。
让我们了解原型如何工作。
因此,对于每个函数,都会创建两个对象,一个用于函数本身,另一个用于其原型。每个函数都有其自己的原型属性,这些属性使其成为函数的原型,因此通过以构造函数模式调用它来创建对象,所创建的对象将成为原型模板的原型,这意味着对象遵循原型的模板,无论在原型中提及了哪些属性或行为,对象都可以访问这些属性。以下的图表可以更清楚地说明这一点。
Function_name.prototype: 它给出一个函数的原型。如果想要从原型返回到函数,需要在原型中找到Constructor属性。 Function_name.prototype.constructor 可以返回到函数。
示例1:
JavaScript
// Constructor
function vehicle(numWheels, price) {
this.numWheels = numWheels;
this.price = price;
this.getPrice = () => {
return this.price;
}
}
var vehicle1 = new vehicle(10, 378979);
var vehicle2 = new vehicle(36, 899768);
// function.prototype works
vehicle.prototype
// function.prototype.constructor works
vehicle.prototype.constructor
输出:
这里的 vehicle.prototype 给出了一个车辆函数的原型。
在这种情况下,vehicle.prototype.constructor给出与原型相同的函数,就像在这种情况下vehicle函数一样,因此它将该函数作为输出。
对象从原型继承属性:
因此,所有创建的对象都将具有对原型的内部引用,这意味着对于每个函数都有一份副本,而所有对象共享该副本,无需创建单独的副本,意味着向函数添加行为而不是从原型访问行为(例如getprice()函数是行为),因此从原型调用它不会将其存储在函数中。
示例2:
Javascript
//constructor
function vehicle(numWheels, price) {
this.numWheels = numWheels;
this.price = price;
}
// Adding behaviour to constructor vehicle
vehicle.prototype.getPrice = function () {
return this.price;
}
var vehicle1 = new vehicle(5, 100000);
var vehicle2 = new vehicle(10, 390000);
// Function or constructor
vehicle
// function.prototype works
vehicle.prototype
// function call using object
vehicle1.getPrice();
输出:
这里构造函数内部没有包含getprice()函数,因为这个函数不能在实际运行的车辆内部占用空间。
但是车辆功能原型包含getprice()函数作为其属性。
vehicle1对象也有在其原型中的getprice()函数。所以它可以轻松地访问getPrice()函数。
在这里,getprice()函数并没有在vehicle函数中占用空间,但对象能够通过原型访问getprice()。尽管getprice()位于函数的原型内部。
.prototype 的更多用法: 它还用于在运行时添加属性,以便每个对象都有一个共同的属性,例如如果有1000辆车,它们都有相同的型号。此查找首先在对象中寻找,然后在原型中搜索该属性。