在 JavaScript 中,每个对象都有一个原型,它可以让我们实现面向对象编程的一些特性,比如继承。本文将深入探讨 JavaScript 原型的工作原理和实际应用。
原型链
JavaScript 的原型是通过“原型链”来实现的。每个对象都有一个内部属性 [[Prototype]]
,指向它的原型对象。如果我们想要使用一个对象的属性或方法,而这个对象本身并没有定义这个属性或方法,JavaScript 引擎就会沿着这个对象的原型链去查找,直到找到该属性或方法为止。
举个例子,假设我们有以下代码:
let person = { name: 'Alice' }; console.log(person.toString());
在这个例子中,我们调用了 person.toString()
方法,但是 person
对象本身并没有定义这个方法。因此,JavaScript 引擎就会沿着 person
对象的原型链去查找。由于 person
对象的原型是 Object.prototype
,而 Object.prototype
上确实定义了 toString()
方法,因此引擎最终找到了该方法并执行了它。
原型对象
JavaScript 中的每个函数都有一个 prototype
属性,它指向该函数的原型对象。当我们使用 new
关键字来创建一个实例时,实例的 [[Prototype]]
属性就会指向该函数的原型对象。这样,实例就可以访问原型对象上定义的属性和方法了。
举个例子,假设我们有以下代码:
-- -------------------- ---- ------- -------- ------------ - --------- - ----- - ---------------------- - ---------- - ------------------- -- ---- -- - - ----------- -- --- ----- - --- ---------------- -------------- -- -- ------- -- ---- -- ------展开代码
在这个例子中,我们定义了一个 Person
构造函数,并将它的原型对象上定义了一个 greet()
方法。然后,我们使用 new
关键字来创建一个 alice
对象,并调用了 alice.greet()
方法。由于 alice
对象本身并没有定义 greet()
方法,因此 JavaScript 引擎就会沿着 alice
对象的原型链去查找。由于 alice
对象的原型是 Person.prototype
,而 Person.prototype
上确实定义了 greet()
方法,因此引擎最终找到了该方法并执行了它。
继承
JavaScript 的原型链机制使得我们可以很方便地实现继承。如果我们想要从一个已有的对象或构造函数中派生出一个新对象或构造函数,只需要将新对象或构造函数的原型设置为已有对象或构造函数的实例即可。
举个例子,假设我们有以下代码:
-- -------------------- ---- ------- -------- -------- -- --------------------- - ---------- - -------------------------- -- -------- --------- - --------- - ----- - ------------- - --- --------- --- --- - --- ------------- ----------- -- -- ------------展开代码
在这个例子中,我们定义了一个 Animal
构造函数,并将它的原型对象上定义了一个 walk()
方法。然后,我们定义了一个 Dog
构造函数,并将它的原型设置为一个 Animal
的实例。这样,Dog
对象就可以继承 Animal
对象的 walk()
方法了。最后,我们创建了一个 dog
对象,并调用了它的 walk()
方法。
总结
JavaScript 原型是通过原型链来实现的,每个对象都有一个内部属性 [[Prototype]]
,指向它的原型对象。JavaScript 中的每个函数都有一个 prototype
属性,它指向该
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/7205