JavaScript中的原型与原型链
原创什么是原型
在JavaScript中,每个对象都有一个特殊的内部属性[[Prototype]](在大多数浏览器中可以通过__proto__访问),这个属性指向另一个对象,也就是该对象的"原型"。
当我们访问一个对象的属性时,如果对象本身没有这个属性,JavaScript引擎会去它的原型对象上查找,如果原型对象上也没有,就会继续查找原型的原型,直到找到该属性或者到达原型链的末端(null)。
// 创建一个简单的对象const animal = { eats: true};// 以animal为原型创建一个新对象const rabbit = { jumps: true};rabbit.__proto__ = animal; // 设置rabbit的原型为animalconsole.log(rabbit.jumps); // true (来自rabbit自身)console.log(rabbit.eats); // true (来自原型animal)构造函数与原型
在JavaScript中,函数也是对象,每个函数都有一个prototype属性(注意不是__proto__)。当这个函数作为构造函数使用时(通过new调用),新创建的对象的[[Prototype]]会指向该函数的prototype对象。
function Person(name) { this.name = name;}// 在Person的原型上添加方法Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`);};const john = new Person('John');john.sayHello(); // Hello, my name is John// john的原型是Person.prototypeconsole.log(john.__proto__ === Person.prototype); // true原型链的查找机制
当访问一个对象的属性时,JavaScript会沿着原型链向上查找:
首先检查对象本身是否有该属性如果没有,检查对象的[[Prototype]](即原型对象)如果还没有,继续检查原型的原型直到找到该属性或者到达nullfunction Animal(name) { this.name = name;}Animal.prototype.eats = true;function Rabbit(name) { this.name = name; this.jumps = true;}// 设置Rabbit.prototype的原型为Animal.prototypeRabbit.prototype = Object.create(Animal.prototype);const whiteRabbit = new Rabbit('White Rabbit');console.log(whiteRabbit.jumps); // true (来自Rabbit实例)console.log(whiteRabbit.eats); // true (来自Animal.prototype)console.log(whiteRabbit.toString); // [function] (来自Object.prototype)// 原型链:// whiteRabbit -> Rabbit.prototype -> Animal.prototype -> Object.prototype -> null现代JavaScript中的原型操作
虽然可以直接使用__proto__,但这不是标准特性。ES6提供了更标准的方法来操作原型:
// 获取原型const proto = Object.getPrototypeOf(rabbit);// 设置原型const newRabbit = Object.create(animal); // 创建新对象并以animal为原型// 检查是否是某对象的原型console.log(animal.isPrototypeOf(rabbit)); // true原型链与继承
原型链是JavaScript实现继承的主要方式。通过设置构造函数的prototype属性,可以建立原型继承关系。
class Animal { constructor(name) { this.name = name; } eat() { console.log(`${this.name} eats.`); }}class Rabbit extends Animal { constructor(name) { super(name); } jump() { console.log(`${this.name} jumps!`); }}const bunny = new Rabbit('Bunny');bunny.eat(); // 继承自Animalbunny.jump(); // Rabbit自身的方法虽然ES6引入了class语法,但它本质上仍然是基于原型的继承,只是提供了更简洁的语法。
理解原型和原型链是掌握JavaScript面向对象编程的关键,它解释了JavaScript中对象如何共享属性和方法,以及继承是如何实现的。
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权本站发表,未经许可,不得转载。
上一篇:JavaScript中的对象解构赋值 下一篇:JavaScript中的数组方法详解
开发学习网





