JavaScript中的原型与原型链
原创什么是原型
在JavaScript中,每个对象都有一个特殊的隐藏属性[[Prototype]](可以通过__proto__访问),它要么是另一个对象,要么是null。这个[[Prototype]]就是我们所说的"原型"。
当我们试图访问一个对象的属性时,JavaScript引擎会先在该对象自身查找,如果没有找到,就会去它的原型对象上查找,然后是原型的原型,依此类推,直到找到该属性或者到达原型链的末端(null)。
// 创建一个对象let animal = { eats: true};// 以animal为原型创建一个新对象let rabbit = { jumps: true, __proto__: animal};console.log(rabbit.jumps); // true (来自rabbit)console.log(rabbit.eats); // true (来自animal)原型链的工作原理
原型链是由多个对象通过[[Prototype]]链接起来的链条。当访问对象属性时,JavaScript会沿着这条链向上查找。
let animal = { eats: true, walk() { console.log("Animal walk"); }};let rabbit = { jumps: true, __proto__: animal};let longEar = { earLength: 10, __proto__: rabbit};// walk方法是从animal继承来的longEar.walk(); // Animal walkconsole.log(longEar.jumps); // true (来自rabbit)函数的prototype属性
每个函数都有一个prototype属性(箭头函数除外),这个属性指向一个对象,当使用new操作符调用函数时,这个对象会成为新创建的实例的原型。
function Person(name) { this.name = name;}// 在原型上添加方法Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`);};let john = new Person("John");john.sayHello(); // Hello, my name is John原型链的终点
所有原型链的终点都是Object.prototype,而Object.prototype的原型是null。
console.log(Object.prototype.__proto__); // null现代设置原型的方法
虽然__proto__被广泛支持,但现代JavaScript提供了更标准的方法来设置和获取原型:
let animal = { eats: true};let rabbit = Object.create(animal); // 以animal为原型创建rabbitrabbit.jumps = true;console.log(Object.getPrototypeOf(rabbit) === animal); // true原型继承的注意事项
写入不触及原型:写入操作只会影响对象自身,不会修改原型。
let animal = { eats: true};let rabbit = { __proto__: animal};rabbit.eats = false; // 在rabbit上创建自己的eats属性console.log(rabbit.eats); // falseconsole.log(animal.eats); // true (原型未受影响)this的值:方法中的this始终是点符号前面的对象,不受原型影响。
let animal = { walk() { console.log(this.name + " walks"); }};let rabbit = { name: "White Rabbit", __proto__: animal};rabbit.walk(); // White Rabbit walks理解原型和原型链是掌握JavaScript面向对象编程的关键,它解释了JavaScript是如何实现继承的,以及对象之间如何共享属性和方法。
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权本站发表,未经许可,不得转载。
开发学习网





