原型(Prototype
)是 JavaScript
中最令人困惑的概念之一,即使是经验丰富的 JavaScript
开发人员也很难理解原型及如何在代码库中应用它。
JavaScript
使用原型(Prototypes
)和构造函数(Constructors
)来模拟类(Class
)。但是在 JavaScript
中,我们并没有类,我们只有对象。那么,我们如何使用对象来实现继承(Inheritance
)呢?
假设我们有一个名为 Car
的对象,我们可以定义另一个对象称为 Vehicle
,并将所有共同的行为或方法添加到 Vehicle
对象中,比如:drive(startLocation, endLocation)
。然后,我们可以将 Car
对象和 Vehicle
对象联系起来。现在,我们将 Vehicle
对象称为 Car
的原型(prototype
)。
因此,原型只是另一个对象的父对象。大多数资料让原型听起来很复杂。因此,每当听到原型这个词时,请知道它只是父对象。
JavaScript
中的每个对象都有一个原型或父对象,除了一个对象。对象继承其原型中定义的所有成员。我们来看看这个过程。
打开 Google Chrome 浏览器并进入开发者工具的控制台选项卡,在控制台中定义一个空对象,如下所示:
你会注意到一个名为[[Prototype]]
的属性。你还会注意到其他属性,如constructor
、hasOwnProperty
等。
每个对象都有一个constructor
属性,它引用用于构造该对象的函数。
让我们看一下x对象的图示表示。
因此,我们在内存中有这个 x
对象,x 对象链接到另一个对象(我们称之为基础对象)。x
对象继承基础对象的属性和方法。
因此,在 JavaScript
中创建的每个对象都是直接或间接继承自基础对象。
因此,基础对象是 JavaScript
中所有对象的根源,并且因此它没有原型或父对象。
假设我们在内存中创建另一个对象,称为 myobject
。
你会发现 x
对象和 myobject
都具有相同的属性和方法,因为它们都继承自相同的基础对象。根据它们是空对象的事实,即它们除了从基础对象继承的属性和方法之外,它们自己没有自己的属性和方法。
在你的浏览器开发工具中,如果你输入 Object.getPrototypeOf(x)
。
你所看到的是基础对象及其成员。像下面这样的表达式将导致 true。可以在浏览器开发工具上尝试一下。
Object.getPrototypeOf(x) === Object.getPrototype(myobject); // true
原因是因为 x
和 myobject
具有完全相同的原型。
当你访问对象的属性或方法时,JavaScript
引擎首先查找该属性是否存在于该对象上,如果找不到,则查找该对象的 [[prototype]]
(即我们所称的基础对象)。在 JavaScript
中,这就是所谓的原型继承。
结论
总的来说,原型是 JavaScript
的一个强大功能,它允许对象从其他对象继承属性和方法。当你想要创建具有相同属性和方法的多个对象时,它们非常重要,这使得你的代码更加干净。