目录
一站搞定原型链:深入理解JavaScript的继承机制
一、基本概念
1. 对象与原型
2. 构造函数
二、原型链
三、原型链的终点
四、原型链的构造
1. 创建对象
2. 原型对象的原型
五、继承
1. 原型继承
2. Class 语法糖
六、总结
作者:watermelo37
涉及领域:Vue、SpingBoot、Docker、LLM、python等
-------------------------------------------------------------------------------------------------------------------------
--------------------------温柔地对待温柔的人,包容的三观就是最大的温柔。--------------------------
-------------------------------------------------------------------------------------------------------------------------
一站搞定原型链:深入理解JavaScript的继承机制
JavaScript 的原型链(prototype chain)是理解 JavaScript 对象和继承机制的关键。它是通过对象的原型(prototype)属性实现的,用于实现对象属性和方法的共享和继承。以下是对 JavaScript 原型链的详细介绍,这一篇文章将会通过理论与demo相结合的方式,力争一文概括原型、对象、原型链以及基于原型链实现JavaScript的继承机制的所有方面,帮助您一站式搞定原型链。
一、基本概念
1. 对象与原型
在 JavaScript 中,每个对象都有一个与之关联的原型对象(prototype)。通过原型,对象可以继承属性和方法。
- prototype:每个函数(包括构造函数但不包括箭头函数)都有一个 prototype 属性,它指向一个对象,这个对象的属性和方法可以被由这个构造函数创建的所有实例对象共享。
- proto:每个 JavaScript 对象都有一个 __proto__ 属性,指向它的原型对象。__proto__ 是对象实例的属性,而 prototype 是构造函数的属性。
2. 构造函数
构造函数是用来创建对象的函数。通过 new 关键字调用构造函数,会创建一个新的对象,并将这个对象的 __proto__ 属性指向构造函数的 prototype 对象。
function Person(name) {this.name = name;
}const person1 = new Person('Alice');
console.log(person1.__proto__ === Person.prototype); // true
二、原型链
原型链是一系列通过 __proto__ 属性相互连接的对象,用于实现属性和方法的继承。如果访问一个对象的属性时,这个对象本身没有该属性,JavaScript 会沿着原型链向上查找,直到找到该属性或达到原型链的末端(即 null)。
function Person(name) {this.name = name;
}Person.prototype.greet = function() {console.log(`Hello, my name is ${this.name}`);
};const person1 = new Person('Alice');
person1.greet(); // Hello, my name is Aliceconsole.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
在上述代码中,当调用 person1.greet() 时,JavaScript 首先检查 person1 对象是否有 greet 方法。如果没有,则沿着原型链查找,最终在 Person.prototype 找到 greet 方法并调用。
三、原型链的终点
原型链的终点是 Object.prototype,它的 __proto__ 属性为 null,表示原型链的终点。
四、原型链的构造
1. 创建对象
通过构造函数创建对象时,新对象的 __proto__ 属性会指向构造函数的 prototype 对象。
function Animal(type) {this.type = type;
}const dog = new Animal('dog');
console.log(dog.__proto__ === Animal.prototype); // true
2. 原型对象的原型
Animal.prototype 本身也是一个对象,它的 __proto__ 属性指向 Object.prototype,这是原型链的一部分。
console.log(Animal.prototype.__proto__ === Object.prototype); // true
五、继承
1. 原型继承
通过设置原型对象实现继承。
function Animal(type) {this.type = type;
}Animal.prototype.speak = function() {console.log(`This ${this.type} makes a sound`);
};function Dog(name) {Animal.call(this, 'dog');this.name = name;
}Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;Dog.prototype.bark = function() {console.log(`${this.name} barks`);
};const dog = new Dog('Buddy');
dog.speak(); // This dog makes a sound
dog.bark(); // Buddy barks
在上述代码中,Dog 继承了 Animal。通过 Object.create(Animal.prototype) 设置 Dog.prototype 的原型为 Animal.prototype,从而实现继承。
2. Class 语法糖
ES6 引入了 class 语法,使得创建和继承类更加简洁。
class Animal {constructor(type) {this.type = type;}speak() {console.log(`This ${this.type} makes a sound`);}
}class Dog extends Animal {constructor(name) {super('dog');this.name = name;}bark() {console.log(`${this.name} barks`);}
}const dog = new Dog('Buddy');
dog.speak(); // This dog makes a sound
dog.bark(); // Buddy barks
六、总结
综上所述,可以得出:
- 原型链是对象通过原型实现属性和方法继承的一种机制。
- 每个对象都有一个 __proto__ 属性,指向它的原型对象。
- 每个函数(包括构造函数)都有一个 prototype 属性,指向一个对象,这个对象的属性和方法可以被实例共享。
- 构造函数创建对象时,新对象的 __proto__ 属性指向构造函数的 prototype 对象。
- 继承可以通过设置原型对象实现,也可以使用 ES6 的 class 语法糖。
只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
更多优质内容,请关注:
分片上传技术全解析:原理、优势与应用(含简单实现源码)
浏览器渲染揭秘:从加载到显示的全过程
你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解
通过array.filter()实现数组的数据筛选、数据清洗和链式调用
el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能
shpfile转GeoJSON且控制转化精度;如何获取GeoJSON?GeoJson结构详解
通过array.reduce()实现数据汇总、条件筛选和映射、对象属性的扁平化、转换数据格式等
极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图
Mapbox添加行政区矢量图层、分级设色图层、自定义鼠标悬浮框、添加天地图底图等
管理数据必备!侦听器watch用法详解